protocols: refactor class member vars (n-t) (#10273)

This commit is contained in:
davc0n
2025-05-04 19:21:36 +02:00
committed by GitHub
parent adbae0f74d
commit 2626f89ea6
41 changed files with 1507 additions and 1511 deletions

View File

@@ -12,7 +12,7 @@
SSessionLockSurface::SSessionLockSurface(SP<CSessionLockSurface> surface_) : surface(surface_) {
pWlrSurface = surface->surface();
listeners.map = surface_->events.map.registerListener([this](std::any data) {
listeners.map = surface_->m_events.map.registerListener([this](std::any data) {
mapped = true;
g_pInputManager->simulateMouseMovement();
@@ -23,14 +23,14 @@ SSessionLockSurface::SSessionLockSurface(SP<CSessionLockSurface> surface_) : sur
g_pHyprRenderer->damageMonitor(PMONITOR);
});
listeners.destroy = surface_->events.destroy.registerListener([this](std::any data) {
listeners.destroy = surface_->m_events.destroy.registerListener([this](std::any data) {
if (pWlrSurface == g_pCompositor->m_lastFocus)
g_pCompositor->m_lastFocus.reset();
g_pSessionLockManager->removeSessionLockSurface(this);
});
listeners.commit = surface_->events.commit.registerListener([this](std::any data) {
listeners.commit = surface_->m_events.commit.registerListener([this](std::any data) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(iMonitorID);
if (mapped && !g_pCompositor->m_lastFocus)
@@ -42,7 +42,7 @@ SSessionLockSurface::SSessionLockSurface(SP<CSessionLockSurface> surface_) : sur
}
CSessionLockManager::CSessionLockManager() {
m_listeners.newLock = PROTO::sessionLock->events.newLock.registerListener([this](std::any data) { this->onNewSessionLock(std::any_cast<SP<CSessionLock>>(data)); });
m_listeners.newLock = PROTO::sessionLock->m_events.newLock.registerListener([this](std::any data) { this->onNewSessionLock(std::any_cast<SP<CSessionLock>>(data)); });
}
void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
@@ -61,7 +61,7 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
m_sessionLock->lock = pLock;
m_sessionLock->mLockTimer.reset();
m_sessionLock->listeners.newSurface = pLock->events.newLockSurface.registerListener([this](std::any data) {
m_sessionLock->listeners.newSurface = pLock->m_events.newLockSurface.registerListener([this](std::any data) {
auto SURFACE = std::any_cast<SP<CSessionLockSurface>>(data);
const auto PMONITOR = SURFACE->monitor();
@@ -71,7 +71,7 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
PROTO::fractional->sendScale(SURFACE->surface(), PMONITOR->m_scale);
});
m_sessionLock->listeners.unlock = pLock->events.unlockAndDestroy.registerListener([this](std::any data) {
m_sessionLock->listeners.unlock = pLock->m_events.unlockAndDestroy.registerListener([this](std::any data) {
m_sessionLock.reset();
g_pInputManager->refocus();
@@ -79,7 +79,7 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
g_pHyprRenderer->damageMonitor(m);
});
m_sessionLock->listeners.destroy = pLock->events.destroyed.registerListener([this](std::any data) {
m_sessionLock->listeners.destroy = pLock->m_events.destroyed.registerListener([this](std::any data) {
m_sessionLock.reset();
g_pCompositor->focusSurface(nullptr);

View File

@@ -11,8 +11,8 @@ CInputMethodRelay::CInputMethodRelay() {
static auto P =
g_pHookSystem->hookDynamic("keyboardFocus", [&](void* self, SCallbackInfo& info, std::any param) { onKeyboardFocus(std::any_cast<SP<CWLSurfaceResource>>(param)); });
m_listeners.newTIV3 = PROTO::textInputV3->events.newTextInput.registerListener([this](std::any ti) { onNewTextInput(std::any_cast<WP<CTextInputV3>>(ti)); });
m_listeners.newTIV1 = PROTO::textInputV1->events.newTextInput.registerListener([this](std::any ti) { onNewTextInput(std::any_cast<WP<CTextInputV1>>(ti)); });
m_listeners.newTIV3 = PROTO::textInputV3->m_events.newTextInput.registerListener([this](std::any ti) { onNewTextInput(std::any_cast<WP<CTextInputV3>>(ti)); });
m_listeners.newTIV1 = PROTO::textInputV1->m_events.newTextInput.registerListener([this](std::any ti) { onNewTextInput(std::any_cast<WP<CTextInputV1>>(ti)); });
m_listeners.newIME = PROTO::ime->m_events.newIME.registerListener([this](std::any ime) { onNewIME(std::any_cast<SP<CInputMethodV2>>(ime)); });
}

View File

@@ -19,11 +19,11 @@ void CTextInput::initCallbacks() {
if (isV3()) {
const auto INPUT = m_v3Input.lock();
m_listeners.enable = INPUT->events.enable.registerListener([this](std::any p) { onEnabled(); });
m_listeners.disable = INPUT->events.disable.registerListener([this](std::any p) { onDisabled(); });
m_listeners.commit = INPUT->events.onCommit.registerListener([this](std::any p) { onCommit(); });
m_listeners.reset = INPUT->events.reset.registerListener([this](std::any p) { onReset(); });
m_listeners.destroy = INPUT->events.destroy.registerListener([this](std::any p) {
m_listeners.enable = INPUT->m_events.enable.registerListener([this](std::any p) { onEnabled(); });
m_listeners.disable = INPUT->m_events.disable.registerListener([this](std::any p) { onDisabled(); });
m_listeners.commit = INPUT->m_events.onCommit.registerListener([this](std::any p) { onCommit(); });
m_listeners.reset = INPUT->m_events.reset.registerListener([this](std::any p) { onReset(); });
m_listeners.destroy = INPUT->m_events.destroy.registerListener([this](std::any p) {
m_listeners.surfaceUnmap.reset();
m_listeners.surfaceDestroy.reset();
g_pInputManager->m_relay.removeTextInput(this);
@@ -36,14 +36,14 @@ void CTextInput::initCallbacks() {
} else {
const auto INPUT = m_v1Input.lock();
m_listeners.enable = INPUT->events.enable.registerListener([this](std::any p) {
m_listeners.enable = INPUT->m_events.enable.registerListener([this](std::any p) {
const auto SURFACE = std::any_cast<SP<CWLSurfaceResource>>(p);
onEnabled(SURFACE);
});
m_listeners.disable = INPUT->events.disable.registerListener([this](std::any p) { onDisabled(); });
m_listeners.commit = INPUT->events.onCommit.registerListener([this](std::any p) { onCommit(); });
m_listeners.reset = INPUT->events.reset.registerListener([this](std::any p) { onReset(); });
m_listeners.destroy = INPUT->events.destroy.registerListener([this](std::any p) {
m_listeners.disable = INPUT->m_events.disable.registerListener([this](std::any p) { onDisabled(); });
m_listeners.commit = INPUT->m_events.onCommit.registerListener([this](std::any p) { onCommit(); });
m_listeners.reset = INPUT->m_events.reset.registerListener([this](std::any p) { onReset(); });
m_listeners.destroy = INPUT->m_events.destroy.registerListener([this](std::any p) {
m_listeners.surfaceUnmap.reset();
m_listeners.surfaceDestroy.reset();
g_pInputManager->m_relay.removeTextInput(this);
@@ -63,7 +63,7 @@ void CTextInput::onEnabled(SP<CWLSurfaceResource> surfV1) {
// v1 only, map surface to PTI
if (!isV3()) {
if (g_pCompositor->m_lastFocus != surfV1 || !m_v1Input->active)
if (g_pCompositor->m_lastFocus != surfV1 || !m_v1Input->m_active)
return;
enter(surfV1);
@@ -115,7 +115,7 @@ void CTextInput::onCommit() {
return;
}
if (!(isV3() ? m_v3Input->current.enabled.value : m_v1Input->active)) {
if (!(isV3() ? m_v3Input->m_current.enabled.value : m_v1Input->m_active)) {
Debug::log(WARN, "Disabled TextInput commit?");
return;
}
@@ -144,11 +144,11 @@ void CTextInput::setFocusedSurface(SP<CWLSurfaceResource> pSurface) {
m_listeners.surfaceUnmap.reset();
m_listeners.surfaceDestroy.reset();
if (isV3() && !m_v3Input.expired() && m_v3Input->current.enabled.value) {
m_v3Input->pending.enabled.value = false;
m_v3Input->pending.enabled.isDisablePending = false;
m_v3Input->pending.enabled.isEnablePending = false;
m_v3Input->current.enabled.value = false;
if (isV3() && !m_v3Input.expired() && m_v3Input->m_current.enabled.value) {
m_v3Input->m_pending.enabled.value = false;
m_v3Input->m_pending.enabled.isDisablePending = false;
m_v3Input->m_pending.enabled.isEnablePending = false;
m_v3Input->m_current.enabled.value = false;
}
if (!g_pInputManager->m_relay.getFocusedTextInput())
@@ -164,11 +164,11 @@ void CTextInput::setFocusedSurface(SP<CWLSurfaceResource> pSurface) {
m_listeners.surfaceUnmap.reset();
m_listeners.surfaceDestroy.reset();
if (isV3() && !m_v3Input.expired() && m_v3Input->current.enabled.value) {
m_v3Input->pending.enabled.value = false;
m_v3Input->pending.enabled.isDisablePending = false;
m_v3Input->pending.enabled.isEnablePending = false;
m_v3Input->current.enabled.value = false;
if (isV3() && !m_v3Input.expired() && m_v3Input->m_current.enabled.value) {
m_v3Input->m_pending.enabled.value = false;
m_v3Input->m_pending.enabled.isDisablePending = false;
m_v3Input->m_pending.enabled.isEnablePending = false;
m_v3Input->m_current.enabled.value = false;
}
if (!g_pInputManager->m_relay.getFocusedTextInput())
@@ -238,23 +238,23 @@ void CTextInput::commitStateToIME(SP<CInputMethodV2> ime) {
if (isV3() && !m_v3Input.expired()) {
const auto INPUT = m_v3Input.lock();
if (INPUT->current.surrounding.updated)
ime->surroundingText(INPUT->current.surrounding.text, INPUT->current.surrounding.cursor, INPUT->current.surrounding.anchor);
if (INPUT->m_current.surrounding.updated)
ime->surroundingText(INPUT->m_current.surrounding.text, INPUT->m_current.surrounding.cursor, INPUT->m_current.surrounding.anchor);
ime->textChangeCause(INPUT->current.cause);
ime->textChangeCause(INPUT->m_current.cause);
if (INPUT->current.contentType.updated)
ime->textContentType(INPUT->current.contentType.hint, INPUT->current.contentType.purpose);
if (INPUT->m_current.contentType.updated)
ime->textContentType(INPUT->m_current.contentType.hint, INPUT->m_current.contentType.purpose);
} else if (!m_v1Input.expired()) {
const auto INPUT = m_v1Input.lock();
if (INPUT->pendingSurrounding.isPending)
ime->surroundingText(INPUT->pendingSurrounding.text, INPUT->pendingSurrounding.cursor, INPUT->pendingSurrounding.anchor);
if (INPUT->m_pendingSurrounding.isPending)
ime->surroundingText(INPUT->m_pendingSurrounding.text, INPUT->m_pendingSurrounding.cursor, INPUT->m_pendingSurrounding.anchor);
ime->textChangeCause(ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD);
if (m_v1Input->pendingContentType.isPending)
ime->textContentType((zwpTextInputV3ContentHint)INPUT->pendingContentType.hint, (zwpTextInputV3ContentPurpose)INPUT->pendingContentType.purpose);
if (m_v1Input->m_pendingContentType.isPending)
ime->textContentType((zwpTextInputV3ContentHint)INPUT->m_pendingContentType.hint, (zwpTextInputV3ContentPurpose)INPUT->m_pendingContentType.purpose);
}
g_pInputManager->m_relay.updateAllPopups();
@@ -282,30 +282,30 @@ void CTextInput::updateIMEState(SP<CInputMethodV2> ime) {
if (ime->m_current.preeditString.committed) {
INPUT->preeditCursor(ime->m_current.preeditString.begin);
INPUT->preeditStyling(0, std::string(ime->m_current.preeditString.string).length(), ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT);
INPUT->preeditString(m_v1Input->serial, ime->m_current.preeditString.string.c_str(), "");
INPUT->preeditString(m_v1Input->m_serial, ime->m_current.preeditString.string.c_str(), "");
} else {
INPUT->preeditCursor(0);
INPUT->preeditStyling(0, 0, ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_HIGHLIGHT);
INPUT->preeditString(m_v1Input->serial, "", "");
INPUT->preeditString(m_v1Input->m_serial, "", "");
}
if (ime->m_current.committedString.committed)
INPUT->commitString(m_v1Input->serial, ime->m_current.committedString.string.c_str());
INPUT->commitString(m_v1Input->m_serial, ime->m_current.committedString.string.c_str());
if (ime->m_current.deleteSurrounding.committed) {
INPUT->deleteSurroundingText(std::string(ime->m_current.preeditString.string).length() - ime->m_current.deleteSurrounding.before,
ime->m_current.deleteSurrounding.after + ime->m_current.deleteSurrounding.before);
if (ime->m_current.preeditString.committed)
INPUT->commitString(m_v1Input->serial, ime->m_current.preeditString.string.c_str());
INPUT->commitString(m_v1Input->m_serial, ime->m_current.preeditString.string.c_str());
}
}
}
bool CTextInput::hasCursorRectangle() {
return !isV3() || m_v3Input->current.box.updated;
return !isV3() || m_v3Input->m_current.box.updated;
}
CBox CTextInput::cursorBox() {
return CBox{isV3() ? m_v3Input->current.box.cursorBox : m_v1Input->cursorRectangle};
return CBox{isV3() ? m_v3Input->m_current.box.cursorBox : m_v1Input->m_cursorRectangle};
}

View File

@@ -7,25 +7,25 @@
using namespace Aquamarine;
COutputManager::COutputManager(SP<CZwlrOutputManagerV1> resource_) : resource(resource_) {
COutputManager::COutputManager(SP<CZwlrOutputManagerV1> resource_) : m_resource(resource_) {
if UNLIKELY (!good())
return;
LOGM(LOG, "New OutputManager registered");
resource->setOnDestroy([this](CZwlrOutputManagerV1* r) { PROTO::outputManagement->destroyResource(this); });
m_resource->setOnDestroy([this](CZwlrOutputManagerV1* r) { PROTO::outputManagement->destroyResource(this); });
resource->setStop([this](CZwlrOutputManagerV1* r) { stopped = true; });
m_resource->setStop([this](CZwlrOutputManagerV1* r) { m_stopped = true; });
resource->setCreateConfiguration([this](CZwlrOutputManagerV1* r, uint32_t id, uint32_t serial) {
m_resource->setCreateConfiguration([this](CZwlrOutputManagerV1* r, uint32_t id, uint32_t serial) {
LOGM(LOG, "Creating new configuration");
const auto RESOURCE = PROTO::outputManagement->m_vConfigurations.emplace_back(
makeShared<COutputConfiguration>(makeShared<CZwlrOutputConfigurationV1>(resource->client(), resource->version(), id), self.lock()));
const auto RESOURCE = PROTO::outputManagement->m_configurations.emplace_back(
makeShared<COutputConfiguration>(makeShared<CZwlrOutputConfigurationV1>(m_resource->client(), m_resource->version(), id), m_self.lock()));
if UNLIKELY (!RESOURCE->good()) {
resource->noMemory();
PROTO::outputManagement->m_vConfigurations.pop_back();
m_resource->noMemory();
PROTO::outputManagement->m_configurations.pop_back();
return;
}
});
@@ -44,25 +44,25 @@ COutputManager::COutputManager(SP<CZwlrOutputManagerV1> resource_) : resource(re
}
bool COutputManager::good() {
return resource->resource();
return m_resource->resource();
}
void COutputManager::makeAndSendNewHead(PHLMONITOR pMonitor) {
if UNLIKELY (stopped)
if UNLIKELY (m_stopped)
return;
const auto RESOURCE =
PROTO::outputManagement->m_vHeads.emplace_back(makeShared<COutputHead>(makeShared<CZwlrOutputHeadV1>(resource->client(), resource->version(), 0), pMonitor));
PROTO::outputManagement->m_heads.emplace_back(makeShared<COutputHead>(makeShared<CZwlrOutputHeadV1>(m_resource->client(), m_resource->version(), 0), pMonitor));
if UNLIKELY (!RESOURCE->good()) {
resource->noMemory();
PROTO::outputManagement->m_vHeads.pop_back();
m_resource->noMemory();
PROTO::outputManagement->m_heads.pop_back();
return;
}
heads.emplace_back(RESOURCE);
m_heads.emplace_back(RESOURCE);
resource->sendHead(RESOURCE->resource.get());
m_resource->sendHead(RESOURCE->m_resource.get());
RESOURCE->sendAllData();
}
@@ -70,13 +70,13 @@ void COutputManager::ensureMonitorSent(PHLMONITOR pMonitor) {
if (pMonitor == g_pCompositor->m_unsafeOutput)
return;
for (auto const& hw : heads) {
for (auto const& hw : m_heads) {
auto h = hw.lock();
if (!h)
continue;
if (h->pMonitor == pMonitor)
if (h->m_monitor == pMonitor)
return;
}
@@ -86,93 +86,93 @@ void COutputManager::ensureMonitorSent(PHLMONITOR pMonitor) {
}
void COutputManager::sendDone() {
resource->sendDone(wl_display_next_serial(g_pCompositor->m_wlDisplay));
m_resource->sendDone(wl_display_next_serial(g_pCompositor->m_wlDisplay));
}
COutputHead::COutputHead(SP<CZwlrOutputHeadV1> resource_, PHLMONITOR pMonitor_) : resource(resource_), pMonitor(pMonitor_) {
COutputHead::COutputHead(SP<CZwlrOutputHeadV1> resource_, PHLMONITOR pMonitor_) : m_resource(resource_), m_monitor(pMonitor_) {
if UNLIKELY (!good())
return;
resource->setRelease([this](CZwlrOutputHeadV1* r) { PROTO::outputManagement->destroyResource(this); });
resource->setOnDestroy([this](CZwlrOutputHeadV1* r) { PROTO::outputManagement->destroyResource(this); });
m_resource->setRelease([this](CZwlrOutputHeadV1* r) { PROTO::outputManagement->destroyResource(this); });
m_resource->setOnDestroy([this](CZwlrOutputHeadV1* r) { PROTO::outputManagement->destroyResource(this); });
listeners.monitorDestroy = pMonitor->m_events.destroy.registerListener([this](std::any d) {
resource->sendFinished();
m_listeners.monitorDestroy = m_monitor->m_events.destroy.registerListener([this](std::any d) {
m_resource->sendFinished();
for (auto const& mw : modes) {
for (auto const& mw : m_modes) {
auto m = mw.lock();
if (!m)
continue;
m->resource->sendFinished();
m->m_resource->sendFinished();
}
pMonitor.reset();
for (auto const& m : PROTO::outputManagement->m_vManagers) {
m_monitor.reset();
for (auto const& m : PROTO::outputManagement->m_managers) {
m->sendDone();
}
});
listeners.monitorModeChange = pMonitor->m_events.modeChanged.registerListener([this](std::any d) { updateMode(); });
m_listeners.monitorModeChange = m_monitor->m_events.modeChanged.registerListener([this](std::any d) { updateMode(); });
}
bool COutputHead::good() {
return resource->resource();
return m_resource->resource();
}
void COutputHead::sendAllData() {
const auto VERSION = resource->version();
const auto VERSION = m_resource->version();
resource->sendName(pMonitor->m_name.c_str());
resource->sendDescription(pMonitor->m_description.c_str());
if (pMonitor->m_output->physicalSize.x > 0 && pMonitor->m_output->physicalSize.y > 0)
resource->sendPhysicalSize(pMonitor->m_output->physicalSize.x, pMonitor->m_output->physicalSize.y);
resource->sendEnabled(pMonitor->m_enabled);
m_resource->sendName(m_monitor->m_name.c_str());
m_resource->sendDescription(m_monitor->m_description.c_str());
if (m_monitor->m_output->physicalSize.x > 0 && m_monitor->m_output->physicalSize.y > 0)
m_resource->sendPhysicalSize(m_monitor->m_output->physicalSize.x, m_monitor->m_output->physicalSize.y);
m_resource->sendEnabled(m_monitor->m_enabled);
if (pMonitor->m_enabled) {
resource->sendPosition(pMonitor->m_position.x, pMonitor->m_position.y);
resource->sendTransform(pMonitor->m_transform);
resource->sendScale(wl_fixed_from_double(pMonitor->m_scale));
if (m_monitor->m_enabled) {
m_resource->sendPosition(m_monitor->m_position.x, m_monitor->m_position.y);
m_resource->sendTransform(m_monitor->m_transform);
m_resource->sendScale(wl_fixed_from_double(m_monitor->m_scale));
}
if (!pMonitor->m_output->make.empty() && VERSION >= 2)
resource->sendMake(pMonitor->m_output->make.c_str());
if (!pMonitor->m_output->model.empty() && VERSION >= 2)
resource->sendModel(pMonitor->m_output->model.c_str());
if (!pMonitor->m_output->serial.empty() && VERSION >= 2)
resource->sendSerialNumber(pMonitor->m_output->serial.c_str());
if (!m_monitor->m_output->make.empty() && VERSION >= 2)
m_resource->sendMake(m_monitor->m_output->make.c_str());
if (!m_monitor->m_output->model.empty() && VERSION >= 2)
m_resource->sendModel(m_monitor->m_output->model.c_str());
if (!m_monitor->m_output->serial.empty() && VERSION >= 2)
m_resource->sendSerialNumber(m_monitor->m_output->serial.c_str());
if (VERSION >= 4)
resource->sendAdaptiveSync(pMonitor->m_vrrActive ? ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_ENABLED : ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_DISABLED);
m_resource->sendAdaptiveSync(m_monitor->m_vrrActive ? ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_ENABLED : ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_DISABLED);
// send all available modes
if (modes.empty()) {
if (!pMonitor->m_output->modes.empty()) {
for (auto const& m : pMonitor->m_output->modes) {
if (m_modes.empty()) {
if (!m_monitor->m_output->modes.empty()) {
for (auto const& m : m_monitor->m_output->modes) {
makeAndSendNewMode(m);
}
} else if (pMonitor->m_output->state->state().customMode) {
makeAndSendNewMode(pMonitor->m_output->state->state().customMode);
} else if (m_monitor->m_output->state->state().customMode) {
makeAndSendNewMode(m_monitor->m_output->state->state().customMode);
} else
makeAndSendNewMode(nullptr);
}
// send current mode
if (pMonitor->m_enabled) {
for (auto const& mw : modes) {
if (m_monitor->m_enabled) {
for (auto const& mw : m_modes) {
auto m = mw.lock();
if (!m)
continue;
if (m->mode == pMonitor->m_output->state->state().mode) {
if (m->mode)
LOGM(LOG, " | sending current mode for {}: {}x{}@{}", pMonitor->m_name, m->mode->pixelSize.x, m->mode->pixelSize.y, m->mode->refreshRate);
if (m->m_mode == m_monitor->m_output->state->state().mode) {
if (m->m_mode)
LOGM(LOG, " | sending current mode for {}: {}x{}@{}", m_monitor->m_name, m->m_mode->pixelSize.x, m->m_mode->pixelSize.y, m->m_mode->refreshRate);
else
LOGM(LOG, " | sending current mode for {}: null (fake)", pMonitor->m_name);
resource->sendCurrentMode(m->resource.get());
LOGM(LOG, " | sending current mode for {}: null (fake)", m_monitor->m_name);
m_resource->sendCurrentMode(m->m_resource.get());
break;
}
}
@@ -180,30 +180,30 @@ void COutputHead::sendAllData() {
}
void COutputHead::updateMode() {
resource->sendEnabled(pMonitor->m_enabled);
m_resource->sendEnabled(m_monitor->m_enabled);
if (pMonitor->m_enabled) {
resource->sendPosition(pMonitor->m_position.x, pMonitor->m_position.y);
resource->sendTransform(pMonitor->m_transform);
resource->sendScale(wl_fixed_from_double(pMonitor->m_scale));
if (m_monitor->m_enabled) {
m_resource->sendPosition(m_monitor->m_position.x, m_monitor->m_position.y);
m_resource->sendTransform(m_monitor->m_transform);
m_resource->sendScale(wl_fixed_from_double(m_monitor->m_scale));
}
if (resource->version() >= 4)
resource->sendAdaptiveSync(pMonitor->m_vrrActive ? ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_ENABLED : ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_DISABLED);
if (m_resource->version() >= 4)
m_resource->sendAdaptiveSync(m_monitor->m_vrrActive ? ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_ENABLED : ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_DISABLED);
if (pMonitor->m_enabled) {
for (auto const& mw : modes) {
if (m_monitor->m_enabled) {
for (auto const& mw : m_modes) {
auto m = mw.lock();
if (!m)
continue;
if (m->mode == pMonitor->m_currentMode) {
if (m->mode)
LOGM(LOG, " | sending current mode for {}: {}x{}@{}", pMonitor->m_name, m->mode->pixelSize.x, m->mode->pixelSize.y, m->mode->refreshRate);
if (m->m_mode == m_monitor->m_currentMode) {
if (m->m_mode)
LOGM(LOG, " | sending current mode for {}: {}x{}@{}", m_monitor->m_name, m->m_mode->pixelSize.x, m->m_mode->pixelSize.y, m->m_mode->refreshRate);
else
LOGM(LOG, " | sending current mode for {}: null (fake)", pMonitor->m_name);
resource->sendCurrentMode(m->resource.get());
LOGM(LOG, " | sending current mode for {}: null (fake)", m_monitor->m_name);
m_resource->sendCurrentMode(m->m_resource.get());
break;
}
}
@@ -211,60 +211,61 @@ void COutputHead::updateMode() {
}
void COutputHead::makeAndSendNewMode(SP<Aquamarine::SOutputMode> mode) {
const auto RESOURCE = PROTO::outputManagement->m_vModes.emplace_back(makeShared<COutputMode>(makeShared<CZwlrOutputModeV1>(resource->client(), resource->version(), 0), mode));
const auto RESOURCE =
PROTO::outputManagement->m_modes.emplace_back(makeShared<COutputMode>(makeShared<CZwlrOutputModeV1>(m_resource->client(), m_resource->version(), 0), mode));
if UNLIKELY (!RESOURCE->good()) {
resource->noMemory();
PROTO::outputManagement->m_vModes.pop_back();
m_resource->noMemory();
PROTO::outputManagement->m_modes.pop_back();
return;
}
modes.emplace_back(RESOURCE);
resource->sendMode(RESOURCE->resource.get());
m_modes.emplace_back(RESOURCE);
m_resource->sendMode(RESOURCE->m_resource.get());
RESOURCE->sendAllData();
}
PHLMONITOR COutputHead::monitor() {
return pMonitor.lock();
return m_monitor.lock();
}
COutputMode::COutputMode(SP<CZwlrOutputModeV1> resource_, SP<Aquamarine::SOutputMode> mode_) : resource(resource_), mode(mode_) {
COutputMode::COutputMode(SP<CZwlrOutputModeV1> resource_, SP<Aquamarine::SOutputMode> mode_) : m_resource(resource_), m_mode(mode_) {
if UNLIKELY (!good())
return;
resource->setRelease([this](CZwlrOutputModeV1* r) { PROTO::outputManagement->destroyResource(this); });
resource->setOnDestroy([this](CZwlrOutputModeV1* r) { PROTO::outputManagement->destroyResource(this); });
m_resource->setRelease([this](CZwlrOutputModeV1* r) { PROTO::outputManagement->destroyResource(this); });
m_resource->setOnDestroy([this](CZwlrOutputModeV1* r) { PROTO::outputManagement->destroyResource(this); });
}
void COutputMode::sendAllData() {
if (!mode)
if (!m_mode)
return;
LOGM(LOG, " | sending mode {}x{}@{}mHz, pref: {}", mode->pixelSize.x, mode->pixelSize.y, mode->refreshRate, mode->preferred);
LOGM(LOG, " | sending mode {}x{}@{}mHz, pref: {}", m_mode->pixelSize.x, m_mode->pixelSize.y, m_mode->refreshRate, m_mode->preferred);
resource->sendSize(mode->pixelSize.x, mode->pixelSize.y);
if (mode->refreshRate > 0)
resource->sendRefresh(mode->refreshRate);
if (mode->preferred)
resource->sendPreferred();
m_resource->sendSize(m_mode->pixelSize.x, m_mode->pixelSize.y);
if (m_mode->refreshRate > 0)
m_resource->sendRefresh(m_mode->refreshRate);
if (m_mode->preferred)
m_resource->sendPreferred();
}
bool COutputMode::good() {
return resource->resource();
return m_resource->resource();
}
SP<Aquamarine::SOutputMode> COutputMode::getMode() {
return mode.lock();
return m_mode.lock();
}
COutputConfiguration::COutputConfiguration(SP<CZwlrOutputConfigurationV1> resource_, SP<COutputManager> owner_) : resource(resource_), owner(owner_) {
COutputConfiguration::COutputConfiguration(SP<CZwlrOutputConfigurationV1> resource_, SP<COutputManager> owner_) : m_resource(resource_), m_owner(owner_) {
if UNLIKELY (!good())
return;
resource->setDestroy([this](CZwlrOutputConfigurationV1* r) { PROTO::outputManagement->destroyResource(this); });
resource->setOnDestroy([this](CZwlrOutputConfigurationV1* r) { PROTO::outputManagement->destroyResource(this); });
m_resource->setDestroy([this](CZwlrOutputConfigurationV1* r) { PROTO::outputManagement->destroyResource(this); });
m_resource->setOnDestroy([this](CZwlrOutputConfigurationV1* r) { PROTO::outputManagement->destroyResource(this); });
resource->setEnableHead([this](CZwlrOutputConfigurationV1* r, uint32_t id, wl_resource* outputHead) {
m_resource->setEnableHead([this](CZwlrOutputConfigurationV1* r, uint32_t id, wl_resource* outputHead) {
const auto HEAD = PROTO::outputManagement->headFromResource(outputHead);
if (!HEAD) {
@@ -279,21 +280,21 @@ COutputConfiguration::COutputConfiguration(SP<CZwlrOutputConfigurationV1> resour
return;
}
const auto RESOURCE = PROTO::outputManagement->m_vConfigurationHeads.emplace_back(
makeShared<COutputConfigurationHead>(makeShared<CZwlrOutputConfigurationHeadV1>(resource->client(), resource->version(), id), PMONITOR));
const auto RESOURCE = PROTO::outputManagement->m_configurationHeads.emplace_back(
makeShared<COutputConfigurationHead>(makeShared<CZwlrOutputConfigurationHeadV1>(m_resource->client(), m_resource->version(), id), PMONITOR));
if UNLIKELY (!RESOURCE->good()) {
resource->noMemory();
PROTO::outputManagement->m_vConfigurationHeads.pop_back();
m_resource->noMemory();
PROTO::outputManagement->m_configurationHeads.pop_back();
return;
}
heads.emplace_back(RESOURCE);
m_heads.emplace_back(RESOURCE);
LOGM(LOG, "enableHead on {}. For now, doing nothing. Waiting for apply().", PMONITOR->m_name);
});
resource->setDisableHead([this](CZwlrOutputConfigurationV1* r, wl_resource* outputHead) {
m_resource->setDisableHead([this](CZwlrOutputConfigurationV1* r, wl_resource* outputHead) {
const auto HEAD = PROTO::outputManagement->headFromResource(outputHead);
if (!HEAD) {
@@ -311,39 +312,39 @@ COutputConfiguration::COutputConfiguration(SP<CZwlrOutputConfigurationV1> resour
LOGM(LOG, "disableHead on {}", PMONITOR->m_name);
SWlrManagerSavedOutputState newState;
if (owner->monitorStates.contains(PMONITOR->m_name))
newState = owner->monitorStates.at(PMONITOR->m_name);
if (m_owner->m_monitorStates.contains(PMONITOR->m_name))
newState = m_owner->m_monitorStates.at(PMONITOR->m_name);
newState.enabled = false;
g_pConfigManager->m_wantsMonitorReload = true;
owner->monitorStates[PMONITOR->m_name] = newState;
m_owner->m_monitorStates[PMONITOR->m_name] = newState;
});
resource->setTest([this](CZwlrOutputConfigurationV1* r) {
m_resource->setTest([this](CZwlrOutputConfigurationV1* r) {
const auto SUCCESS = applyTestConfiguration(true);
if (SUCCESS)
resource->sendSucceeded();
m_resource->sendSucceeded();
else
resource->sendFailed();
m_resource->sendFailed();
});
resource->setApply([this](CZwlrOutputConfigurationV1* r) {
m_resource->setApply([this](CZwlrOutputConfigurationV1* r) {
const auto SUCCESS = applyTestConfiguration(false);
if (SUCCESS)
resource->sendSucceeded();
m_resource->sendSucceeded();
else
resource->sendFailed();
m_resource->sendFailed();
owner->sendDone();
m_owner->sendDone();
});
}
bool COutputConfiguration::good() {
return resource->resource();
return m_resource->resource();
}
bool COutputConfiguration::applyTestConfiguration(bool test) {
@@ -354,18 +355,18 @@ bool COutputConfiguration::applyTestConfiguration(bool test) {
LOGM(LOG, "Applying configuration");
if (!owner) {
if (!m_owner) {
LOGM(ERR, "applyTestConfiguration: no owner?!");
return false;
}
for (auto const& headw : heads) {
for (auto const& headw : m_heads) {
auto head = headw.lock();
if (!head)
continue;
const auto PMONITOR = head->pMonitor;
const auto PMONITOR = head->m_monitor;
if (!PMONITOR)
continue;
@@ -373,53 +374,53 @@ bool COutputConfiguration::applyTestConfiguration(bool test) {
LOGM(LOG, "Saving config for monitor {}", PMONITOR->m_name);
SWlrManagerSavedOutputState newState;
if (owner->monitorStates.contains(PMONITOR->m_name))
newState = owner->monitorStates.at(PMONITOR->m_name);
if (m_owner->m_monitorStates.contains(PMONITOR->m_name))
newState = m_owner->m_monitorStates.at(PMONITOR->m_name);
newState.enabled = true;
if (head->state.committedProperties & eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_MODE) {
newState.resolution = head->state.mode->getMode()->pixelSize;
newState.refresh = head->state.mode->getMode()->refreshRate;
if (head->m_state.committedProperties & eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_MODE) {
newState.resolution = head->m_state.mode->getMode()->pixelSize;
newState.refresh = head->m_state.mode->getMode()->refreshRate;
newState.committedProperties |= eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_MODE;
LOGM(LOG, " > Mode: {:.0f}x{:.0f}@{}mHz", newState.resolution.x, newState.resolution.y, newState.refresh);
} else if (head->state.committedProperties & eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_CUSTOM_MODE) {
newState.resolution = head->state.customMode.size;
newState.refresh = head->state.customMode.refresh;
} else if (head->m_state.committedProperties & eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_CUSTOM_MODE) {
newState.resolution = head->m_state.customMode.size;
newState.refresh = head->m_state.customMode.refresh;
newState.committedProperties |= eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_CUSTOM_MODE;
LOGM(LOG, " > Custom mode: {:.0f}x{:.0f}@{}mHz", newState.resolution.x, newState.resolution.y, newState.refresh);
}
if (head->state.committedProperties & eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_POSITION) {
newState.position = head->state.position;
if (head->m_state.committedProperties & eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_POSITION) {
newState.position = head->m_state.position;
newState.committedProperties |= eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_POSITION;
LOGM(LOG, " > Position: {:.0f}, {:.0f}", head->state.position.x, head->state.position.y);
LOGM(LOG, " > Position: {:.0f}, {:.0f}", head->m_state.position.x, head->m_state.position.y);
}
if (head->state.committedProperties & eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_ADAPTIVE_SYNC) {
newState.adaptiveSync = head->state.adaptiveSync;
if (head->m_state.committedProperties & eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_ADAPTIVE_SYNC) {
newState.adaptiveSync = head->m_state.adaptiveSync;
newState.committedProperties |= eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_ADAPTIVE_SYNC;
LOGM(LOG, " > vrr: {}", newState.adaptiveSync);
}
if (head->state.committedProperties & eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_SCALE) {
newState.scale = head->state.scale;
if (head->m_state.committedProperties & eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_SCALE) {
newState.scale = head->m_state.scale;
newState.committedProperties |= eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_SCALE;
LOGM(LOG, " > scale: {:.2f}", newState.scale);
}
if (head->state.committedProperties & eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_TRANSFORM) {
newState.transform = head->state.transform;
if (head->m_state.committedProperties & eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_TRANSFORM) {
newState.transform = head->m_state.transform;
newState.committedProperties |= eWlrOutputCommittedProperties::OUTPUT_HEAD_COMMITTED_TRANSFORM;
LOGM(LOG, " > transform: {}", (uint8_t)newState.transform);
}
// reset properties for next set.
head->state.committedProperties = 0;
head->m_state.committedProperties = 0;
g_pConfigManager->m_wantsMonitorReload = true;
owner->monitorStates[PMONITOR->m_name] = newState;
m_owner->m_monitorStates[PMONITOR->m_name] = newState;
}
LOGM(LOG, "Saved configuration");
@@ -427,13 +428,13 @@ bool COutputConfiguration::applyTestConfiguration(bool test) {
return true;
}
COutputConfigurationHead::COutputConfigurationHead(SP<CZwlrOutputConfigurationHeadV1> resource_, PHLMONITOR pMonitor_) : resource(resource_), pMonitor(pMonitor_) {
COutputConfigurationHead::COutputConfigurationHead(SP<CZwlrOutputConfigurationHeadV1> resource_, PHLMONITOR pMonitor_) : m_resource(resource_), m_monitor(pMonitor_) {
if UNLIKELY (!good())
return;
resource->setOnDestroy([this](CZwlrOutputConfigurationHeadV1* r) { PROTO::outputManagement->destroyResource(this); });
m_resource->setOnDestroy([this](CZwlrOutputConfigurationHeadV1* r) { PROTO::outputManagement->destroyResource(this); });
resource->setSetMode([this](CZwlrOutputConfigurationHeadV1* r, wl_resource* outputMode) {
m_resource->setSetMode([this](CZwlrOutputConfigurationHeadV1* r, wl_resource* outputMode) {
const auto MODE = PROTO::outputManagement->modeFromResource(outputMode);
if (!MODE || !MODE->getMode()) {
@@ -441,137 +442,137 @@ COutputConfigurationHead::COutputConfigurationHead(SP<CZwlrOutputConfigurationHe
return;
}
if (!pMonitor) {
if (!m_monitor) {
LOGM(ERR, "setMode on inert resource");
return;
}
if (state.committedProperties & OUTPUT_HEAD_COMMITTED_MODE) {
resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_ALREADY_SET, "Property already set");
if (m_state.committedProperties & OUTPUT_HEAD_COMMITTED_MODE) {
m_resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_ALREADY_SET, "Property already set");
return;
}
state.committedProperties |= OUTPUT_HEAD_COMMITTED_MODE;
state.mode = MODE;
m_state.committedProperties |= OUTPUT_HEAD_COMMITTED_MODE;
m_state.mode = MODE;
LOGM(LOG, " | configHead for {}: set mode to {}x{}@{}", pMonitor->m_name, MODE->getMode()->pixelSize.x, MODE->getMode()->pixelSize.y, MODE->getMode()->refreshRate);
LOGM(LOG, " | configHead for {}: set mode to {}x{}@{}", m_monitor->m_name, MODE->getMode()->pixelSize.x, MODE->getMode()->pixelSize.y, MODE->getMode()->refreshRate);
});
resource->setSetCustomMode([this](CZwlrOutputConfigurationHeadV1* r, int32_t w, int32_t h, int32_t refresh) {
if (!pMonitor) {
m_resource->setSetCustomMode([this](CZwlrOutputConfigurationHeadV1* r, int32_t w, int32_t h, int32_t refresh) {
if (!m_monitor) {
LOGM(ERR, "setCustomMode on inert resource");
return;
}
if (state.committedProperties & OUTPUT_HEAD_COMMITTED_CUSTOM_MODE) {
resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_ALREADY_SET, "Property already set");
if (m_state.committedProperties & OUTPUT_HEAD_COMMITTED_CUSTOM_MODE) {
m_resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_ALREADY_SET, "Property already set");
return;
}
if (w <= 0 || h <= 0 || refresh < 0) {
resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_INVALID_CUSTOM_MODE, "Invalid mode");
m_resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_INVALID_CUSTOM_MODE, "Invalid mode");
return;
}
if (refresh == 0) {
LOGM(LOG, " | configHead for {}: refreshRate 0, using old refresh rate of {:.2f}Hz", pMonitor->m_name, pMonitor->m_refreshRate);
refresh = std::round(pMonitor->m_refreshRate * 1000.F);
LOGM(LOG, " | configHead for {}: refreshRate 0, using old refresh rate of {:.2f}Hz", m_monitor->m_name, m_monitor->m_refreshRate);
refresh = std::round(m_monitor->m_refreshRate * 1000.F);
}
state.committedProperties |= OUTPUT_HEAD_COMMITTED_CUSTOM_MODE;
state.customMode = {{w, h}, (uint32_t)refresh};
m_state.committedProperties |= OUTPUT_HEAD_COMMITTED_CUSTOM_MODE;
m_state.customMode = {{w, h}, (uint32_t)refresh};
LOGM(LOG, " | configHead for {}: set custom mode to {}x{}@{}", pMonitor->m_name, w, h, refresh);
LOGM(LOG, " | configHead for {}: set custom mode to {}x{}@{}", m_monitor->m_name, w, h, refresh);
});
resource->setSetPosition([this](CZwlrOutputConfigurationHeadV1* r, int32_t x, int32_t y) {
if (!pMonitor) {
m_resource->setSetPosition([this](CZwlrOutputConfigurationHeadV1* r, int32_t x, int32_t y) {
if (!m_monitor) {
LOGM(ERR, "setMode on inert resource");
return;
}
if (state.committedProperties & OUTPUT_HEAD_COMMITTED_POSITION) {
resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_ALREADY_SET, "Property already set");
if (m_state.committedProperties & OUTPUT_HEAD_COMMITTED_POSITION) {
m_resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_ALREADY_SET, "Property already set");
return;
}
state.committedProperties |= OUTPUT_HEAD_COMMITTED_POSITION;
state.position = {x, y};
m_state.committedProperties |= OUTPUT_HEAD_COMMITTED_POSITION;
m_state.position = {x, y};
LOGM(LOG, " | configHead for {}: set pos to {}, {}", pMonitor->m_name, x, y);
LOGM(LOG, " | configHead for {}: set pos to {}, {}", m_monitor->m_name, x, y);
});
resource->setSetTransform([this](CZwlrOutputConfigurationHeadV1* r, int32_t transform) {
if (!pMonitor) {
m_resource->setSetTransform([this](CZwlrOutputConfigurationHeadV1* r, int32_t transform) {
if (!m_monitor) {
LOGM(ERR, "setMode on inert resource");
return;
}
if (state.committedProperties & OUTPUT_HEAD_COMMITTED_TRANSFORM) {
resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_ALREADY_SET, "Property already set");
if (m_state.committedProperties & OUTPUT_HEAD_COMMITTED_TRANSFORM) {
m_resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_ALREADY_SET, "Property already set");
return;
}
if (transform < 0 || transform > 7) {
resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_INVALID_TRANSFORM, "Invalid transform");
m_resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_INVALID_TRANSFORM, "Invalid transform");
return;
}
state.committedProperties |= OUTPUT_HEAD_COMMITTED_TRANSFORM;
state.transform = (wl_output_transform)transform;
m_state.committedProperties |= OUTPUT_HEAD_COMMITTED_TRANSFORM;
m_state.transform = (wl_output_transform)transform;
LOGM(LOG, " | configHead for {}: set transform to {}", pMonitor->m_name, transform);
LOGM(LOG, " | configHead for {}: set transform to {}", m_monitor->m_name, transform);
});
resource->setSetScale([this](CZwlrOutputConfigurationHeadV1* r, wl_fixed_t scale_) {
if (!pMonitor) {
m_resource->setSetScale([this](CZwlrOutputConfigurationHeadV1* r, wl_fixed_t scale_) {
if (!m_monitor) {
LOGM(ERR, "setMode on inert resource");
return;
}
if (state.committedProperties & OUTPUT_HEAD_COMMITTED_SCALE) {
resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_ALREADY_SET, "Property already set");
if (m_state.committedProperties & OUTPUT_HEAD_COMMITTED_SCALE) {
m_resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_ALREADY_SET, "Property already set");
return;
}
double scale = wl_fixed_to_double(scale_);
if (scale < 0.1 || scale > 10.0) {
resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_INVALID_SCALE, "Invalid scale");
m_resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_INVALID_SCALE, "Invalid scale");
return;
}
state.committedProperties |= OUTPUT_HEAD_COMMITTED_SCALE;
state.scale = scale;
m_state.committedProperties |= OUTPUT_HEAD_COMMITTED_SCALE;
m_state.scale = scale;
LOGM(LOG, " | configHead for {}: set scale to {:.2f}", pMonitor->m_name, scale);
LOGM(LOG, " | configHead for {}: set scale to {:.2f}", m_monitor->m_name, scale);
});
resource->setSetAdaptiveSync([this](CZwlrOutputConfigurationHeadV1* r, uint32_t as) {
if (!pMonitor) {
m_resource->setSetAdaptiveSync([this](CZwlrOutputConfigurationHeadV1* r, uint32_t as) {
if (!m_monitor) {
LOGM(ERR, "setMode on inert resource");
return;
}
if (state.committedProperties & OUTPUT_HEAD_COMMITTED_ADAPTIVE_SYNC) {
resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_ALREADY_SET, "Property already set");
if (m_state.committedProperties & OUTPUT_HEAD_COMMITTED_ADAPTIVE_SYNC) {
m_resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_ALREADY_SET, "Property already set");
return;
}
if (as > 1) {
resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_INVALID_ADAPTIVE_SYNC_STATE, "Invalid adaptive sync state");
m_resource->error(ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_INVALID_ADAPTIVE_SYNC_STATE, "Invalid adaptive sync state");
return;
}
state.committedProperties |= OUTPUT_HEAD_COMMITTED_ADAPTIVE_SYNC;
state.adaptiveSync = as;
m_state.committedProperties |= OUTPUT_HEAD_COMMITTED_ADAPTIVE_SYNC;
m_state.adaptiveSync = as;
LOGM(LOG, " | configHead for {}: set adaptiveSync to {}", pMonitor->m_name, as);
LOGM(LOG, " | configHead for {}: set adaptiveSync to {}", m_monitor->m_name, as);
});
}
bool COutputConfigurationHead::good() {
return resource->resource();
return m_resource->resource();
}
COutputManagementProtocol::COutputManagementProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -579,48 +580,48 @@ COutputManagementProtocol::COutputManagementProtocol(const wl_interface* iface,
}
void COutputManagementProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeShared<COutputManager>(makeShared<CZwlrOutputManagerV1>(client, ver, id)));
const auto RESOURCE = m_managers.emplace_back(makeShared<COutputManager>(makeShared<CZwlrOutputManagerV1>(client, ver, id)));
if UNLIKELY (!RESOURCE->good()) {
wl_client_post_no_memory(client);
m_vManagers.pop_back();
m_managers.pop_back();
return;
}
RESOURCE->self = RESOURCE;
RESOURCE->m_self = RESOURCE;
}
void COutputManagementProtocol::destroyResource(COutputManager* resource) {
std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_managers, [&](const auto& other) { return other.get() == resource; });
}
void COutputManagementProtocol::destroyResource(COutputHead* resource) {
std::erase_if(m_vHeads, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_heads, [&](const auto& other) { return other.get() == resource; });
}
void COutputManagementProtocol::destroyResource(COutputMode* resource) {
std::erase_if(m_vModes, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_modes, [&](const auto& other) { return other.get() == resource; });
}
void COutputManagementProtocol::destroyResource(COutputConfiguration* resource) {
std::erase_if(m_vConfigurations, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_configurations, [&](const auto& other) { return other.get() == resource; });
}
void COutputManagementProtocol::destroyResource(COutputConfigurationHead* resource) {
std::erase_if(m_vConfigurationHeads, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_configurationHeads, [&](const auto& other) { return other.get() == resource; });
}
void COutputManagementProtocol::updateAllOutputs() {
for (auto const& m : g_pCompositor->m_realMonitors) {
for (auto const& mgr : m_vManagers) {
for (auto const& mgr : m_managers) {
mgr->ensureMonitorSent(m);
}
}
}
SP<COutputHead> COutputManagementProtocol::headFromResource(wl_resource* r) {
for (auto const& h : m_vHeads) {
if (h->resource->resource() == r)
for (auto const& h : m_heads) {
if (h->m_resource->resource() == r)
return h;
}
@@ -628,8 +629,8 @@ SP<COutputHead> COutputManagementProtocol::headFromResource(wl_resource* r) {
}
SP<COutputMode> COutputManagementProtocol::modeFromResource(wl_resource* r) {
for (auto const& h : m_vModes) {
if (h->resource->resource() == r)
for (auto const& h : m_modes) {
if (h->m_resource->resource() == r)
return h;
}
@@ -637,11 +638,11 @@ SP<COutputMode> COutputManagementProtocol::modeFromResource(wl_resource* r) {
}
SP<SWlrManagerSavedOutputState> COutputManagementProtocol::getOutputStateFor(PHLMONITOR pMonitor) {
for (auto const& m : m_vManagers) {
if (!m->monitorStates.contains(pMonitor->m_name))
for (auto const& m : m_managers) {
if (!m->m_monitorStates.contains(pMonitor->m_name))
continue;
return makeShared<SWlrManagerSavedOutputState>(m->monitorStates.at(pMonitor->m_name));
return makeShared<SWlrManagerSavedOutputState>(m->m_monitorStates.at(pMonitor->m_name));
}
return nullptr;

View File

@@ -59,15 +59,15 @@ class COutputManager {
void sendDone();
// holds the states for this manager.
std::unordered_map<std::string, SWlrManagerSavedOutputState> monitorStates;
std::unordered_map<std::string, SWlrManagerSavedOutputState> m_monitorStates;
private:
SP<CZwlrOutputManagerV1> resource;
bool stopped = false;
SP<CZwlrOutputManagerV1> m_resource;
bool m_stopped = false;
WP<COutputManager> self;
WP<COutputManager> m_self;
std::vector<WP<COutputHead>> heads;
std::vector<WP<COutputHead>> m_heads;
void makeAndSendNewHead(PHLMONITOR pMonitor);
friend class COutputManagementProtocol;
@@ -82,8 +82,8 @@ class COutputMode {
void sendAllData();
private:
SP<CZwlrOutputModeV1> resource;
WP<Aquamarine::SOutputMode> mode;
SP<CZwlrOutputModeV1> m_resource;
WP<Aquamarine::SOutputMode> m_mode;
friend class COutputHead;
friend class COutputManagementProtocol;
@@ -99,18 +99,18 @@ class COutputHead {
PHLMONITOR monitor();
private:
SP<CZwlrOutputHeadV1> resource;
PHLMONITORREF pMonitor;
SP<CZwlrOutputHeadV1> m_resource;
PHLMONITORREF m_monitor;
void makeAndSendNewMode(SP<Aquamarine::SOutputMode> mode);
void sendCurrentMode();
std::vector<WP<COutputMode>> modes;
std::vector<WP<COutputMode>> m_modes;
struct {
CHyprSignalListener monitorDestroy;
CHyprSignalListener monitorModeChange;
} listeners;
} m_listeners;
friend class COutputManager;
friend class COutputManagementProtocol;
@@ -122,11 +122,11 @@ class COutputConfigurationHead {
bool good();
SWlrManagerOutputState state;
SWlrManagerOutputState m_state;
private:
SP<CZwlrOutputConfigurationHeadV1> resource;
PHLMONITORREF pMonitor;
SP<CZwlrOutputConfigurationHeadV1> m_resource;
PHLMONITORREF m_monitor;
friend class COutputConfiguration;
};
@@ -138,9 +138,9 @@ class COutputConfiguration {
bool good();
private:
SP<CZwlrOutputConfigurationV1> resource;
std::vector<WP<COutputConfigurationHead>> heads;
WP<COutputManager> owner;
SP<CZwlrOutputConfigurationV1> m_resource;
std::vector<WP<COutputConfigurationHead>> m_heads;
WP<COutputManager> m_owner;
bool applyTestConfiguration(bool test);
};
@@ -164,11 +164,11 @@ class COutputManagementProtocol : public IWaylandProtocol {
void updateAllOutputs();
//
std::vector<SP<COutputManager>> m_vManagers;
std::vector<SP<COutputHead>> m_vHeads;
std::vector<SP<COutputMode>> m_vModes;
std::vector<SP<COutputConfiguration>> m_vConfigurations;
std::vector<SP<COutputConfigurationHead>> m_vConfigurationHeads;
std::vector<SP<COutputManager>> m_managers;
std::vector<SP<COutputHead>> m_heads;
std::vector<SP<COutputMode>> m_modes;
std::vector<SP<COutputConfiguration>> m_configurations;
std::vector<SP<COutputConfigurationHead>> m_configurationHeads;
SP<COutputHead> headFromResource(wl_resource* r);
SP<COutputMode> modeFromResource(wl_resource* r);

View File

@@ -2,40 +2,40 @@
#include "core/Output.hpp"
#include "../helpers/Monitor.hpp"
COutputPower::COutputPower(SP<CZwlrOutputPowerV1> resource_, PHLMONITOR pMonitor_) : resource(resource_), pMonitor(pMonitor_) {
if UNLIKELY (!resource->resource())
COutputPower::COutputPower(SP<CZwlrOutputPowerV1> resource_, PHLMONITOR pMonitor_) : m_resource(resource_), m_monitor(pMonitor_) {
if UNLIKELY (!m_resource->resource())
return;
resource->setDestroy([this](CZwlrOutputPowerV1* r) { PROTO::outputPower->destroyOutputPower(this); });
resource->setOnDestroy([this](CZwlrOutputPowerV1* r) { PROTO::outputPower->destroyOutputPower(this); });
m_resource->setDestroy([this](CZwlrOutputPowerV1* r) { PROTO::outputPower->destroyOutputPower(this); });
m_resource->setOnDestroy([this](CZwlrOutputPowerV1* r) { PROTO::outputPower->destroyOutputPower(this); });
resource->setSetMode([this](CZwlrOutputPowerV1* r, zwlrOutputPowerV1Mode mode) {
if (!pMonitor)
m_resource->setSetMode([this](CZwlrOutputPowerV1* r, zwlrOutputPowerV1Mode mode) {
if (!m_monitor)
return;
pMonitor->m_dpmsStatus = mode == ZWLR_OUTPUT_POWER_V1_MODE_ON;
m_monitor->m_dpmsStatus = mode == ZWLR_OUTPUT_POWER_V1_MODE_ON;
pMonitor->m_output->state->setEnabled(mode == ZWLR_OUTPUT_POWER_V1_MODE_ON);
m_monitor->m_output->state->setEnabled(mode == ZWLR_OUTPUT_POWER_V1_MODE_ON);
if (!pMonitor->m_state.commit())
LOGM(ERR, "Couldn't set dpms to {} for {}", pMonitor->m_dpmsStatus, pMonitor->m_name);
if (!m_monitor->m_state.commit())
LOGM(ERR, "Couldn't set dpms to {} for {}", m_monitor->m_dpmsStatus, m_monitor->m_name);
});
resource->sendMode(pMonitor->m_dpmsStatus ? ZWLR_OUTPUT_POWER_V1_MODE_ON : ZWLR_OUTPUT_POWER_V1_MODE_OFF);
m_resource->sendMode(m_monitor->m_dpmsStatus ? ZWLR_OUTPUT_POWER_V1_MODE_ON : ZWLR_OUTPUT_POWER_V1_MODE_OFF);
listeners.monitorDestroy = pMonitor->m_events.destroy.registerListener([this](std::any v) {
pMonitor.reset();
resource->sendFailed();
m_listeners.monitorDestroy = m_monitor->m_events.destroy.registerListener([this](std::any v) {
m_monitor.reset();
m_resource->sendFailed();
});
listeners.monitorDpms = pMonitor->m_events.dpmsChanged.registerListener(
[this](std::any v) { resource->sendMode(pMonitor->m_dpmsStatus ? ZWLR_OUTPUT_POWER_V1_MODE_ON : ZWLR_OUTPUT_POWER_V1_MODE_OFF); });
listeners.monitorState = pMonitor->m_events.modeChanged.registerListener(
[this](std::any v) { resource->sendMode(pMonitor->m_dpmsStatus ? ZWLR_OUTPUT_POWER_V1_MODE_ON : ZWLR_OUTPUT_POWER_V1_MODE_OFF); });
m_listeners.monitorDpms = m_monitor->m_events.dpmsChanged.registerListener(
[this](std::any v) { m_resource->sendMode(m_monitor->m_dpmsStatus ? ZWLR_OUTPUT_POWER_V1_MODE_ON : ZWLR_OUTPUT_POWER_V1_MODE_OFF); });
m_listeners.monitorState = m_monitor->m_events.modeChanged.registerListener(
[this](std::any v) { m_resource->sendMode(m_monitor->m_dpmsStatus ? ZWLR_OUTPUT_POWER_V1_MODE_ON : ZWLR_OUTPUT_POWER_V1_MODE_OFF); });
}
bool COutputPower::good() {
return resource->resource();
return m_resource->resource();
}
COutputPowerProtocol::COutputPowerProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -43,7 +43,7 @@ COutputPowerProtocol::COutputPowerProtocol(const wl_interface* iface, const int&
}
void COutputPowerProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeUnique<CZwlrOutputPowerManagerV1>(client, ver, id)).get();
const auto RESOURCE = m_managers.emplace_back(makeUnique<CZwlrOutputPowerManagerV1>(client, ver, id)).get();
RESOURCE->setOnDestroy([this](CZwlrOutputPowerManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setDestroy([this](CZwlrOutputPowerManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
@@ -51,11 +51,11 @@ void COutputPowerProtocol::bindManager(wl_client* client, void* data, uint32_t v
}
void COutputPowerProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
std::erase_if(m_managers, [&](const auto& other) { return other->resource() == res; });
}
void COutputPowerProtocol::destroyOutputPower(COutputPower* power) {
std::erase_if(m_vOutputPowers, [&](const auto& other) { return other.get() == power; });
std::erase_if(m_outputPowers, [&](const auto& other) { return other.get() == power; });
}
void COutputPowerProtocol::onGetOutputPower(CZwlrOutputPowerManagerV1* pMgr, uint32_t id, wl_resource* output) {
@@ -68,11 +68,11 @@ void COutputPowerProtocol::onGetOutputPower(CZwlrOutputPowerManagerV1* pMgr, uin
}
const auto CLIENT = pMgr->client();
const auto RESOURCE = m_vOutputPowers.emplace_back(makeUnique<COutputPower>(makeShared<CZwlrOutputPowerV1>(CLIENT, pMgr->version(), id), OUTPUT->m_monitor.lock())).get();
const auto RESOURCE = m_outputPowers.emplace_back(makeUnique<COutputPower>(makeShared<CZwlrOutputPowerV1>(CLIENT, pMgr->version(), id), OUTPUT->m_monitor.lock())).get();
if UNLIKELY (!RESOURCE->good()) {
pMgr->noMemory();
m_vOutputPowers.pop_back();
m_outputPowers.pop_back();
return;
}
}

View File

@@ -15,15 +15,15 @@ class COutputPower {
bool good();
private:
SP<CZwlrOutputPowerV1> resource;
SP<CZwlrOutputPowerV1> m_resource;
PHLMONITORREF pMonitor;
PHLMONITORREF m_monitor;
struct {
CHyprSignalListener monitorDestroy;
CHyprSignalListener monitorState;
CHyprSignalListener monitorDpms;
} listeners;
} m_listeners;
};
class COutputPowerProtocol : public IWaylandProtocol {
@@ -38,8 +38,8 @@ class COutputPowerProtocol : public IWaylandProtocol {
void onGetOutputPower(CZwlrOutputPowerManagerV1* pMgr, uint32_t id, wl_resource* output);
//
std::vector<UP<CZwlrOutputPowerManagerV1>> m_vManagers;
std::vector<UP<COutputPower>> m_vOutputPowers;
std::vector<UP<CZwlrOutputPowerManagerV1>> m_managers;
std::vector<UP<COutputPower>> m_outputPowers;
friend class COutputPower;
};

View File

@@ -9,38 +9,38 @@
#include "../helpers/Monitor.hpp"
CPointerConstraint::CPointerConstraint(SP<CZwpLockedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime_) :
resourceL(resource_), locked(true), lifetime(lifetime_) {
m_resourceLocked(resource_), m_locked(true), m_lifetime(lifetime_) {
if UNLIKELY (!resource_->resource())
return;
resource_->setOnDestroy([this](CZwpLockedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); });
resource_->setDestroy([this](CZwpLockedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); });
pHLSurface = CWLSurface::fromResource(surf);
m_hlSurface = CWLSurface::fromResource(surf);
if (!pHLSurface)
if (!m_hlSurface)
return;
if (region_)
region.set(CWLRegionResource::fromResource(region_)->m_region);
m_region.set(CWLRegionResource::fromResource(region_)->m_region);
resource_->setSetRegion([this](CZwpLockedPointerV1* p, wl_resource* region) { onSetRegion(region); });
resource_->setSetCursorPositionHint([this](CZwpLockedPointerV1* p, wl_fixed_t x, wl_fixed_t y) {
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
if (!pHLSurface)
if (!m_hlSurface)
return;
hintSet = true;
m_hintSet = true;
float scale = 1.f;
const auto PWINDOW = pHLSurface->getWindow();
const auto PWINDOW = m_hlSurface->getWindow();
if (PWINDOW) {
const auto ISXWL = PWINDOW->m_isX11;
scale = ISXWL && *PXWLFORCESCALEZERO ? PWINDOW->m_X11SurfaceScaledBy : 1.f;
}
positionHint = {wl_fixed_to_double(x) / scale, wl_fixed_to_double(y) / scale};
m_positionHint = {wl_fixed_to_double(x) / scale, wl_fixed_to_double(y) / scale};
g_pInputManager->simulateMouseMovement();
});
@@ -48,20 +48,20 @@ CPointerConstraint::CPointerConstraint(SP<CZwpLockedPointerV1> resource_, SP<CWL
}
CPointerConstraint::CPointerConstraint(SP<CZwpConfinedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime_) :
resourceC(resource_), lifetime(lifetime_) {
m_resourceConfined(resource_), m_lifetime(lifetime_) {
if UNLIKELY (!resource_->resource())
return;
resource_->setOnDestroy([this](CZwpConfinedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); });
resource_->setDestroy([this](CZwpConfinedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); });
pHLSurface = CWLSurface::fromResource(surf);
m_hlSurface = CWLSurface::fromResource(surf);
if (!pHLSurface)
if (!m_hlSurface)
return;
if (region_)
region.set(CWLRegionResource::fromResource(region_)->m_region);
m_region.set(CWLRegionResource::fromResource(region_)->m_region);
resource_->setSetRegion([this](CZwpConfinedPointerV1* p, wl_resource* region) { onSetRegion(region); });
@@ -74,15 +74,15 @@ CPointerConstraint::~CPointerConstraint() {
return !SHP || SHP.get() == this;
});
if (pHLSurface)
pHLSurface->m_constraint.reset();
if (m_hlSurface)
m_hlSurface->m_constraint.reset();
}
void CPointerConstraint::sharedConstructions() {
if (pHLSurface) {
listeners.destroySurface = pHLSurface->m_events.destroy.registerListener([this](std::any d) {
pHLSurface.reset();
if (active)
if (m_hlSurface) {
m_listeners.destroySurface = m_hlSurface->m_events.destroy.registerListener([this](std::any d) {
m_hlSurface.reset();
if (m_active)
deactivate();
std::erase_if(g_pInputManager->m_constraints, [this](const auto& c) {
@@ -92,26 +92,26 @@ void CPointerConstraint::sharedConstructions() {
});
}
cursorPosOnActivate = g_pInputManager->getMouseCoordsInternal();
m_cursorPosOnActivate = g_pInputManager->getMouseCoordsInternal();
}
bool CPointerConstraint::good() {
return locked ? resourceL->resource() : resourceC->resource();
return m_locked ? m_resourceLocked->resource() : m_resourceConfined->resource();
}
void CPointerConstraint::deactivate() {
if (!active)
if (!m_active)
return;
if (locked)
resourceL->sendUnlocked();
if (m_locked)
m_resourceLocked->sendUnlocked();
else
resourceC->sendUnconfined();
m_resourceConfined->sendUnconfined();
active = false;
m_active = false;
if (lifetime == ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT) {
dead = true;
if (m_lifetime == ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT) {
m_dead = true;
// remove from inputmgr
std::erase_if(g_pInputManager->m_constraints, [this](const auto& c) {
const auto SHP = c.lock();
@@ -121,50 +121,50 @@ void CPointerConstraint::deactivate() {
}
void CPointerConstraint::activate() {
if (dead || active)
if (m_dead || m_active)
return;
// TODO: hack, probably not a super duper great idea
if (g_pSeatManager->m_state.pointerFocus != pHLSurface->resource()) {
const auto SURFBOX = pHLSurface->getSurfaceBoxGlobal();
if (g_pSeatManager->m_state.pointerFocus != m_hlSurface->resource()) {
const auto SURFBOX = m_hlSurface->getSurfaceBoxGlobal();
const auto LOCAL = SURFBOX.has_value() ? logicPositionHint() - SURFBOX->pos() : Vector2D{};
g_pSeatManager->setPointerFocus(pHLSurface->resource(), LOCAL);
g_pSeatManager->setPointerFocus(m_hlSurface->resource(), LOCAL);
}
if (locked)
resourceL->sendLocked();
if (m_locked)
m_resourceLocked->sendLocked();
else
resourceC->sendConfined();
m_resourceConfined->sendConfined();
active = true;
m_active = true;
g_pInputManager->simulateMouseMovement();
}
bool CPointerConstraint::isActive() {
return active;
return m_active;
}
void CPointerConstraint::onSetRegion(wl_resource* wlRegion) {
if (!wlRegion) {
region.clear();
m_region.clear();
return;
}
const auto REGION = region.set(CWLRegionResource::fromResource(wlRegion)->m_region);
const auto REGION = m_region.set(CWLRegionResource::fromResource(wlRegion)->m_region);
region.set(REGION);
positionHint = region.closestPoint(positionHint);
m_region.set(REGION);
m_positionHint = m_region.closestPoint(m_positionHint);
g_pInputManager->simulateMouseMovement(); // to warp the cursor if anything's amiss
}
SP<CWLSurface> CPointerConstraint::owner() {
return pHLSurface.lock();
return m_hlSurface.lock();
}
CRegion CPointerConstraint::logicConstraintRegion() {
CRegion rg = region;
const auto SURFBOX = pHLSurface->getSurfaceBoxGlobal();
CRegion rg = m_region;
const auto SURFBOX = m_hlSurface->getSurfaceBoxGlobal();
// if region wasn't set in pointer-constraints request take surface region
if (rg.empty() && SURFBOX.has_value()) {
@@ -178,17 +178,17 @@ CRegion CPointerConstraint::logicConstraintRegion() {
}
bool CPointerConstraint::isLocked() {
return locked;
return m_locked;
}
Vector2D CPointerConstraint::logicPositionHint() {
if UNLIKELY (!pHLSurface)
if UNLIKELY (!m_hlSurface)
return {};
const auto SURFBOX = pHLSurface->getSurfaceBoxGlobal();
const auto SURFBOX = m_hlSurface->getSurfaceBoxGlobal();
const auto CONSTRAINTPOS = SURFBOX.has_value() ? SURFBOX->pos() : Vector2D{};
return hintSet ? CONSTRAINTPOS + positionHint : cursorPosOnActivate;
return m_hintSet ? CONSTRAINTPOS + m_positionHint : m_cursorPosOnActivate;
}
CPointerConstraintsProtocol::CPointerConstraintsProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -196,7 +196,7 @@ CPointerConstraintsProtocol::CPointerConstraintsProtocol(const wl_interface* ifa
}
void CPointerConstraintsProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeUnique<CZwpPointerConstraintsV1>(client, ver, id)).get();
const auto RESOURCE = m_managers.emplace_back(makeUnique<CZwpPointerConstraintsV1>(client, ver, id)).get();
RESOURCE->setOnDestroy([this](CZwpPointerConstraintsV1* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setDestroy([this](CZwpPointerConstraintsV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
@@ -207,18 +207,18 @@ void CPointerConstraintsProtocol::bindManager(wl_client* client, void* data, uin
}
void CPointerConstraintsProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
std::erase_if(m_managers, [&](const auto& other) { return other->resource() == res; });
}
void CPointerConstraintsProtocol::destroyPointerConstraint(CPointerConstraint* hyprlandEgg) {
std::erase_if(m_vConstraints, [&](const auto& other) { return other.get() == hyprlandEgg; });
std::erase_if(m_constraints, [&](const auto& other) { return other.get() == hyprlandEgg; });
}
void CPointerConstraintsProtocol::onNewConstraint(SP<CPointerConstraint> constraint, CZwpPointerConstraintsV1* pMgr) {
if UNLIKELY (!constraint->good()) {
LOGM(ERR, "Couldn't create constraint??");
pMgr->noMemory();
m_vConstraints.pop_back();
m_constraints.pop_back();
return;
}
@@ -229,12 +229,12 @@ void CPointerConstraintsProtocol::onNewConstraint(SP<CPointerConstraint> constra
const auto OWNER = constraint->owner();
const auto DUPES = std::count_if(m_vConstraints.begin(), m_vConstraints.end(), [OWNER](const auto& c) { return c->owner() == OWNER; });
const auto DUPES = std::count_if(m_constraints.begin(), m_constraints.end(), [OWNER](const auto& c) { return c->owner() == OWNER; });
if UNLIKELY (DUPES > 1) {
LOGM(ERR, "Constraint for surface duped");
pMgr->error(ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED, "Surface already confined");
m_vConstraints.pop_back();
m_constraints.pop_back();
return;
}
@@ -249,7 +249,7 @@ void CPointerConstraintsProtocol::onNewConstraint(SP<CPointerConstraint> constra
void CPointerConstraintsProtocol::onLockPointer(CZwpPointerConstraintsV1* pMgr, uint32_t id, wl_resource* surface, wl_resource* pointer, wl_resource* region,
zwpPointerConstraintsV1Lifetime lifetime) {
const auto CLIENT = pMgr->client();
const auto RESOURCE = m_vConstraints.emplace_back(
const auto RESOURCE = m_constraints.emplace_back(
makeShared<CPointerConstraint>(makeShared<CZwpLockedPointerV1>(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surface), region, lifetime));
onNewConstraint(RESOURCE, pMgr);
@@ -258,7 +258,7 @@ void CPointerConstraintsProtocol::onLockPointer(CZwpPointerConstraintsV1* pMgr,
void CPointerConstraintsProtocol::onConfinePointer(CZwpPointerConstraintsV1* pMgr, uint32_t id, wl_resource* surface, wl_resource* pointer, wl_resource* region,
zwpPointerConstraintsV1Lifetime lifetime) {
const auto CLIENT = pMgr->client();
const auto RESOURCE = m_vConstraints.emplace_back(
const auto RESOURCE = m_constraints.emplace_back(
makeShared<CPointerConstraint>(makeShared<CZwpConfinedPointerV1>(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surface), region, lifetime));
onNewConstraint(RESOURCE, pMgr);

View File

@@ -31,26 +31,26 @@ class CPointerConstraint {
Vector2D logicPositionHint();
private:
SP<CZwpLockedPointerV1> resourceL;
SP<CZwpConfinedPointerV1> resourceC;
SP<CZwpLockedPointerV1> m_resourceLocked;
SP<CZwpConfinedPointerV1> m_resourceConfined;
WP<CWLSurface> pHLSurface;
WP<CWLSurface> m_hlSurface;
CRegion region;
bool hintSet = false;
Vector2D positionHint = {-1, -1};
Vector2D cursorPosOnActivate = {-1, -1};
bool active = false;
bool locked = false;
bool dead = false;
zwpPointerConstraintsV1Lifetime lifetime = ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT;
CRegion m_region;
bool m_hintSet = false;
Vector2D m_positionHint = {-1, -1};
Vector2D m_cursorPosOnActivate = {-1, -1};
bool m_active = false;
bool m_locked = false;
bool m_dead = false;
zwpPointerConstraintsV1Lifetime m_lifetime = ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT;
void sharedConstructions();
void onSetRegion(wl_resource* region);
struct {
CHyprSignalListener destroySurface;
} listeners;
} m_listeners;
};
class CPointerConstraintsProtocol : public IWaylandProtocol {
@@ -67,8 +67,8 @@ class CPointerConstraintsProtocol : public IWaylandProtocol {
void onNewConstraint(SP<CPointerConstraint> constraint, CZwpPointerConstraintsV1* pMgr);
//
std::vector<UP<CZwpPointerConstraintsV1>> m_vManagers;
std::vector<SP<CPointerConstraint>> m_vConstraints;
std::vector<UP<CZwpPointerConstraintsV1>> m_managers;
std::vector<SP<CPointerConstraint>> m_constraints;
friend class CPointerConstraint;
};

View File

@@ -3,40 +3,40 @@
#include "core/Seat.hpp"
#include "core/Compositor.hpp"
CPointerGestureSwipe::CPointerGestureSwipe(SP<CZwpPointerGestureSwipeV1> resource_) : resource(resource_) {
if UNLIKELY (!resource->resource())
CPointerGestureSwipe::CPointerGestureSwipe(SP<CZwpPointerGestureSwipeV1> resource_) : m_resource(resource_) {
if UNLIKELY (!m_resource->resource())
return;
resource->setOnDestroy([this](CZwpPointerGestureSwipeV1* p) { PROTO::pointerGestures->onGestureDestroy(this); });
resource->setDestroy([this](CZwpPointerGestureSwipeV1* p) { PROTO::pointerGestures->onGestureDestroy(this); });
m_resource->setOnDestroy([this](CZwpPointerGestureSwipeV1* p) { PROTO::pointerGestures->onGestureDestroy(this); });
m_resource->setDestroy([this](CZwpPointerGestureSwipeV1* p) { PROTO::pointerGestures->onGestureDestroy(this); });
}
bool CPointerGestureSwipe::good() {
return resource->resource();
return m_resource->resource();
}
CPointerGestureHold::CPointerGestureHold(SP<CZwpPointerGestureHoldV1> resource_) : resource(resource_) {
if UNLIKELY (!resource->resource())
CPointerGestureHold::CPointerGestureHold(SP<CZwpPointerGestureHoldV1> resource_) : m_resource(resource_) {
if UNLIKELY (!m_resource->resource())
return;
resource->setOnDestroy([this](CZwpPointerGestureHoldV1* p) { PROTO::pointerGestures->onGestureDestroy(this); });
resource->setDestroy([this](CZwpPointerGestureHoldV1* p) { PROTO::pointerGestures->onGestureDestroy(this); });
m_resource->setOnDestroy([this](CZwpPointerGestureHoldV1* p) { PROTO::pointerGestures->onGestureDestroy(this); });
m_resource->setDestroy([this](CZwpPointerGestureHoldV1* p) { PROTO::pointerGestures->onGestureDestroy(this); });
}
bool CPointerGestureHold::good() {
return resource->resource();
return m_resource->resource();
}
CPointerGesturePinch::CPointerGesturePinch(SP<CZwpPointerGesturePinchV1> resource_) : resource(resource_) {
if UNLIKELY (!resource->resource())
CPointerGesturePinch::CPointerGesturePinch(SP<CZwpPointerGesturePinchV1> resource_) : m_resource(resource_) {
if UNLIKELY (!m_resource->resource())
return;
resource->setOnDestroy([this](CZwpPointerGesturePinchV1* p) { PROTO::pointerGestures->onGestureDestroy(this); });
resource->setDestroy([this](CZwpPointerGesturePinchV1* p) { PROTO::pointerGestures->onGestureDestroy(this); });
m_resource->setOnDestroy([this](CZwpPointerGesturePinchV1* p) { PROTO::pointerGestures->onGestureDestroy(this); });
m_resource->setDestroy([this](CZwpPointerGesturePinchV1* p) { PROTO::pointerGestures->onGestureDestroy(this); });
}
bool CPointerGesturePinch::good() {
return resource->resource();
return m_resource->resource();
}
CPointerGesturesProtocol::CPointerGesturesProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -44,7 +44,7 @@ CPointerGesturesProtocol::CPointerGesturesProtocol(const wl_interface* iface, co
}
void CPointerGesturesProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeUnique<CZwpPointerGesturesV1>(client, ver, id)).get();
const auto RESOURCE = m_managers.emplace_back(makeUnique<CZwpPointerGesturesV1>(client, ver, id)).get();
RESOURCE->setOnDestroy([this](CZwpPointerGesturesV1* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setRelease([this](CZwpPointerGesturesV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
@@ -54,24 +54,24 @@ void CPointerGesturesProtocol::bindManager(wl_client* client, void* data, uint32
}
void CPointerGesturesProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
std::erase_if(m_managers, [&](const auto& other) { return other->resource() == res; });
}
void CPointerGesturesProtocol::onGestureDestroy(CPointerGestureSwipe* gesture) {
std::erase_if(m_vSwipes, [&](const auto& other) { return other.get() == gesture; });
std::erase_if(m_swipes, [&](const auto& other) { return other.get() == gesture; });
}
void CPointerGesturesProtocol::onGestureDestroy(CPointerGesturePinch* gesture) {
std::erase_if(m_vPinches, [&](const auto& other) { return other.get() == gesture; });
std::erase_if(m_pinches, [&](const auto& other) { return other.get() == gesture; });
}
void CPointerGesturesProtocol::onGestureDestroy(CPointerGestureHold* gesture) {
std::erase_if(m_vHolds, [&](const auto& other) { return other.get() == gesture; });
std::erase_if(m_holds, [&](const auto& other) { return other.get() == gesture; });
}
void CPointerGesturesProtocol::onGetPinchGesture(CZwpPointerGesturesV1* pMgr, uint32_t id, wl_resource* pointer) {
const auto CLIENT = pMgr->client();
const auto RESOURCE = m_vPinches.emplace_back(makeUnique<CPointerGesturePinch>(makeShared<CZwpPointerGesturePinchV1>(CLIENT, pMgr->version(), id))).get();
const auto RESOURCE = m_pinches.emplace_back(makeUnique<CPointerGesturePinch>(makeShared<CZwpPointerGesturePinchV1>(CLIENT, pMgr->version(), id))).get();
if UNLIKELY (!RESOURCE->good()) {
pMgr->noMemory();
@@ -82,7 +82,7 @@ void CPointerGesturesProtocol::onGetPinchGesture(CZwpPointerGesturesV1* pMgr, ui
void CPointerGesturesProtocol::onGetSwipeGesture(CZwpPointerGesturesV1* pMgr, uint32_t id, wl_resource* pointer) {
const auto CLIENT = pMgr->client();
const auto RESOURCE = m_vSwipes.emplace_back(makeUnique<CPointerGestureSwipe>(makeShared<CZwpPointerGestureSwipeV1>(CLIENT, pMgr->version(), id))).get();
const auto RESOURCE = m_swipes.emplace_back(makeUnique<CPointerGestureSwipe>(makeShared<CZwpPointerGestureSwipeV1>(CLIENT, pMgr->version(), id))).get();
if UNLIKELY (!RESOURCE->good()) {
pMgr->noMemory();
@@ -93,7 +93,7 @@ void CPointerGesturesProtocol::onGetSwipeGesture(CZwpPointerGesturesV1* pMgr, ui
void CPointerGesturesProtocol::onGetHoldGesture(CZwpPointerGesturesV1* pMgr, uint32_t id, wl_resource* pointer) {
const auto CLIENT = pMgr->client();
const auto RESOURCE = m_vHolds.emplace_back(makeUnique<CPointerGestureHold>(makeShared<CZwpPointerGestureHoldV1>(CLIENT, pMgr->version(), id))).get();
const auto RESOURCE = m_holds.emplace_back(makeUnique<CPointerGestureHold>(makeShared<CZwpPointerGestureHoldV1>(CLIENT, pMgr->version(), id))).get();
if UNLIKELY (!RESOURCE->good()) {
pMgr->noMemory();
@@ -110,11 +110,11 @@ void CPointerGesturesProtocol::swipeBegin(uint32_t timeMs, uint32_t fingers) {
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->m_state.pointerFocusResource.lock());
for (auto const& sw : m_vSwipes) {
if (sw->resource->client() != FOCUSEDCLIENT)
for (auto const& sw : m_swipes) {
if (sw->m_resource->client() != FOCUSEDCLIENT)
continue;
sw->resource->sendBegin(SERIAL, timeMs, g_pSeatManager->m_state.pointerFocus->getResource()->resource(), fingers);
sw->m_resource->sendBegin(SERIAL, timeMs, g_pSeatManager->m_state.pointerFocus->getResource()->resource(), fingers);
}
}
@@ -124,11 +124,11 @@ void CPointerGesturesProtocol::swipeUpdate(uint32_t timeMs, const Vector2D& delt
const auto FOCUSEDCLIENT = g_pSeatManager->m_state.pointerFocusResource->client();
for (auto const& sw : m_vSwipes) {
if (sw->resource->client() != FOCUSEDCLIENT)
for (auto const& sw : m_swipes) {
if (sw->m_resource->client() != FOCUSEDCLIENT)
continue;
sw->resource->sendUpdate(timeMs, wl_fixed_from_double(delta.x), wl_fixed_from_double(delta.y));
sw->m_resource->sendUpdate(timeMs, wl_fixed_from_double(delta.x), wl_fixed_from_double(delta.y));
}
}
@@ -140,11 +140,11 @@ void CPointerGesturesProtocol::swipeEnd(uint32_t timeMs, bool cancelled) {
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->m_state.pointerFocusResource.lock());
for (auto const& sw : m_vSwipes) {
if (sw->resource->client() != FOCUSEDCLIENT)
for (auto const& sw : m_swipes) {
if (sw->m_resource->client() != FOCUSEDCLIENT)
continue;
sw->resource->sendEnd(SERIAL, timeMs, cancelled);
sw->m_resource->sendEnd(SERIAL, timeMs, cancelled);
}
}
@@ -156,11 +156,11 @@ void CPointerGesturesProtocol::pinchBegin(uint32_t timeMs, uint32_t fingers) {
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->m_state.pointerFocusResource.lock());
for (auto const& sw : m_vPinches) {
if (sw->resource->client() != FOCUSEDCLIENT)
for (auto const& sw : m_pinches) {
if (sw->m_resource->client() != FOCUSEDCLIENT)
continue;
sw->resource->sendBegin(SERIAL, timeMs, g_pSeatManager->m_state.pointerFocus->getResource()->resource(), fingers);
sw->m_resource->sendBegin(SERIAL, timeMs, g_pSeatManager->m_state.pointerFocus->getResource()->resource(), fingers);
}
}
@@ -170,11 +170,11 @@ void CPointerGesturesProtocol::pinchUpdate(uint32_t timeMs, const Vector2D& delt
const auto FOCUSEDCLIENT = g_pSeatManager->m_state.pointerFocusResource->client();
for (auto const& sw : m_vPinches) {
if (sw->resource->client() != FOCUSEDCLIENT)
for (auto const& sw : m_pinches) {
if (sw->m_resource->client() != FOCUSEDCLIENT)
continue;
sw->resource->sendUpdate(timeMs, wl_fixed_from_double(delta.x), wl_fixed_from_double(delta.y), wl_fixed_from_double(scale), wl_fixed_from_double(rotation));
sw->m_resource->sendUpdate(timeMs, wl_fixed_from_double(delta.x), wl_fixed_from_double(delta.y), wl_fixed_from_double(scale), wl_fixed_from_double(rotation));
}
}
@@ -186,11 +186,11 @@ void CPointerGesturesProtocol::pinchEnd(uint32_t timeMs, bool cancelled) {
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->m_state.pointerFocusResource.lock());
for (auto const& sw : m_vPinches) {
if (sw->resource->client() != FOCUSEDCLIENT)
for (auto const& sw : m_pinches) {
if (sw->m_resource->client() != FOCUSEDCLIENT)
continue;
sw->resource->sendEnd(SERIAL, timeMs, cancelled);
sw->m_resource->sendEnd(SERIAL, timeMs, cancelled);
}
}
@@ -202,11 +202,11 @@ void CPointerGesturesProtocol::holdBegin(uint32_t timeMs, uint32_t fingers) {
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->m_state.pointerFocusResource.lock());
for (auto const& sw : m_vHolds) {
if (sw->resource->client() != FOCUSEDCLIENT)
for (auto const& sw : m_holds) {
if (sw->m_resource->client() != FOCUSEDCLIENT)
continue;
sw->resource->sendBegin(SERIAL, timeMs, g_pSeatManager->m_state.pointerFocus->getResource()->resource(), fingers);
sw->m_resource->sendBegin(SERIAL, timeMs, g_pSeatManager->m_state.pointerFocus->getResource()->resource(), fingers);
}
}
@@ -218,10 +218,10 @@ void CPointerGesturesProtocol::holdEnd(uint32_t timeMs, bool cancelled) {
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->m_state.pointerFocusResource.lock());
for (auto const& sw : m_vHolds) {
if (sw->resource->client() != FOCUSEDCLIENT)
for (auto const& sw : m_holds) {
if (sw->m_resource->client() != FOCUSEDCLIENT)
continue;
sw->resource->sendEnd(SERIAL, timeMs, cancelled);
sw->m_resource->sendEnd(SERIAL, timeMs, cancelled);
}
}

View File

@@ -12,7 +12,7 @@ class CPointerGestureSwipe {
bool good();
private:
SP<CZwpPointerGestureSwipeV1> resource;
SP<CZwpPointerGestureSwipeV1> m_resource;
friend class CPointerGesturesProtocol;
};
@@ -24,7 +24,7 @@ class CPointerGesturePinch {
bool good();
private:
SP<CZwpPointerGesturePinchV1> resource;
SP<CZwpPointerGesturePinchV1> m_resource;
friend class CPointerGesturesProtocol;
};
@@ -36,7 +36,7 @@ class CPointerGestureHold {
bool good();
private:
SP<CZwpPointerGestureHoldV1> resource;
SP<CZwpPointerGestureHoldV1> m_resource;
friend class CPointerGesturesProtocol;
};
@@ -68,10 +68,10 @@ class CPointerGesturesProtocol : public IWaylandProtocol {
void onGetHoldGesture(CZwpPointerGesturesV1* pMgr, uint32_t id, wl_resource* pointer);
//
std::vector<UP<CZwpPointerGesturesV1>> m_vManagers;
std::vector<UP<CPointerGestureSwipe>> m_vSwipes;
std::vector<UP<CPointerGesturePinch>> m_vPinches;
std::vector<UP<CPointerGestureHold>> m_vHolds;
std::vector<UP<CZwpPointerGesturesV1>> m_managers;
std::vector<UP<CPointerGestureSwipe>> m_swipes;
std::vector<UP<CPointerGesturePinch>> m_pinches;
std::vector<UP<CPointerGestureHold>> m_holds;
friend class CPointerGestureHold;
friend class CPointerGesturePinch;

View File

@@ -6,52 +6,52 @@
#include "core/Output.hpp"
#include <aquamarine/output/Output.hpp>
CQueuedPresentationData::CQueuedPresentationData(SP<CWLSurfaceResource> surf) : surface(surf) {
CQueuedPresentationData::CQueuedPresentationData(SP<CWLSurfaceResource> surf) : m_surface(surf) {
;
}
void CQueuedPresentationData::setPresentationType(bool zeroCopy_) {
zeroCopy = zeroCopy_;
m_zeroCopy = zeroCopy_;
}
void CQueuedPresentationData::attachMonitor(PHLMONITOR pMonitor_) {
pMonitor = pMonitor_;
m_monitor = pMonitor_;
}
void CQueuedPresentationData::presented() {
wasPresented = true;
m_wasPresented = true;
}
void CQueuedPresentationData::discarded() {
wasPresented = false;
m_wasPresented = false;
}
CPresentationFeedback::CPresentationFeedback(SP<CWpPresentationFeedback> resource_, SP<CWLSurfaceResource> surf) : resource(resource_), surface(surf) {
CPresentationFeedback::CPresentationFeedback(SP<CWpPresentationFeedback> resource_, SP<CWLSurfaceResource> surf) : m_resource(resource_), m_surface(surf) {
if UNLIKELY (!good())
return;
resource->setOnDestroy([this](CWpPresentationFeedback* pMgr) {
if (!done) // if it's done, it's probably already destroyed. If not, it will be in a sec.
m_resource->setOnDestroy([this](CWpPresentationFeedback* pMgr) {
if (!m_done) // if it's done, it's probably already destroyed. If not, it will be in a sec.
PROTO::presentation->destroyResource(this);
});
}
bool CPresentationFeedback::good() {
return resource->resource();
return m_resource->resource();
}
void CPresentationFeedback::sendQueued(SP<CQueuedPresentationData> data, const Time::steady_tp& when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags) {
auto client = resource->client();
auto client = m_resource->client();
if LIKELY (PROTO::outputs.contains(data->pMonitor->m_name)) {
if LIKELY (auto outputResource = PROTO::outputs.at(data->pMonitor->m_name)->outputResourceFrom(client); outputResource)
resource->sendSyncOutput(outputResource->getResource()->resource());
if LIKELY (PROTO::outputs.contains(data->m_monitor->m_name)) {
if LIKELY (auto outputResource = PROTO::outputs.at(data->m_monitor->m_name)->outputResourceFrom(client); outputResource)
m_resource->sendSyncOutput(outputResource->getResource()->resource());
}
uint32_t flags = 0;
if (!data->pMonitor->m_tearingState.activelyTearing)
if (!data->m_monitor->m_tearingState.activelyTearing)
flags |= WP_PRESENTATION_FEEDBACK_KIND_VSYNC;
if (data->zeroCopy)
if (data->m_zeroCopy)
flags |= WP_PRESENTATION_FEEDBACK_KIND_ZERO_COPY;
if (reportedFlags & Aquamarine::IOutput::AQ_OUTPUT_PRESENT_HW_CLOCK)
flags |= WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK;
@@ -64,24 +64,24 @@ void CPresentationFeedback::sendQueued(SP<CQueuedPresentationData> data, const T
if (sizeof(time_t) > 4)
tv_sec = TIMESPEC.tv_sec >> 32;
if (data->wasPresented)
resource->sendPresented((uint32_t)tv_sec, (uint32_t)(TIMESPEC.tv_sec & 0xFFFFFFFF), (uint32_t)(TIMESPEC.tv_nsec), untilRefreshNs, (uint32_t)(seq >> 32),
(uint32_t)(seq & 0xFFFFFFFF), (wpPresentationFeedbackKind)flags);
if (data->m_wasPresented)
m_resource->sendPresented((uint32_t)tv_sec, (uint32_t)(TIMESPEC.tv_sec & 0xFFFFFFFF), (uint32_t)(TIMESPEC.tv_nsec), untilRefreshNs, (uint32_t)(seq >> 32),
(uint32_t)(seq & 0xFFFFFFFF), (wpPresentationFeedbackKind)flags);
else
resource->sendDiscarded();
m_resource->sendDiscarded();
done = true;
m_done = true;
}
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) {
const auto PMONITOR = PHLMONITORREF{std::any_cast<PHLMONITOR>(param)};
std::erase_if(m_vQueue, [PMONITOR](const auto& other) { return !other->surface || other->pMonitor == PMONITOR; });
std::erase_if(m_queue, [PMONITOR](const auto& other) { return !other->m_surface || other->m_monitor == PMONITOR; });
});
}
void CPresentationProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeUnique<CWpPresentation>(client, ver, id)).get();
const auto RESOURCE = m_managers.emplace_back(makeUnique<CWpPresentation>(client, ver, id)).get();
RESOURCE->setOnDestroy([this](CWpPresentation* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setDestroy([this](CWpPresentation* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
@@ -89,50 +89,49 @@ void CPresentationProtocol::bindManager(wl_client* client, void* data, uint32_t
}
void CPresentationProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
std::erase_if(m_managers, [&](const auto& other) { return other->resource() == res; });
}
void CPresentationProtocol::destroyResource(CPresentationFeedback* feedback) {
std::erase_if(m_vFeedbacks, [&](const auto& other) { return other.get() == feedback; });
std::erase_if(m_feedbacks, [&](const auto& other) { return other.get() == feedback; });
}
void CPresentationProtocol::onGetFeedback(CWpPresentation* pMgr, wl_resource* surf, uint32_t id) {
const auto CLIENT = pMgr->client();
const auto RESOURCE =
m_vFeedbacks.emplace_back(makeShared<CPresentationFeedback>(makeShared<CWpPresentationFeedback>(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surf)))
.get();
m_feedbacks.emplace_back(makeShared<CPresentationFeedback>(makeShared<CWpPresentationFeedback>(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surf))).get();
if UNLIKELY (!RESOURCE->good()) {
pMgr->noMemory();
m_vFeedbacks.pop_back();
m_feedbacks.pop_back();
return;
}
}
void CPresentationProtocol::onPresented(PHLMONITOR pMonitor, const Time::steady_tp& when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags) {
for (auto const& feedback : m_vFeedbacks) {
if (!feedback->surface)
for (auto const& feedback : m_feedbacks) {
if (!feedback->m_surface)
continue;
for (auto const& data : m_vQueue) {
if (!data->surface || data->surface != feedback->surface || (data->pMonitor && data->pMonitor != pMonitor))
for (auto const& data : m_queue) {
if (!data->m_surface || data->m_surface != feedback->m_surface || (data->m_monitor && data->m_monitor != pMonitor))
continue;
feedback->sendQueued(data, when, untilRefreshNs, seq, reportedFlags);
feedback->done = true;
feedback->m_done = true;
break;
}
}
if (m_vFeedbacks.size() > 10000 /* arbitrary number I chose as fitting */) {
LOGM(ERR, "FIXME: presentation has a feedback leak, and has grown to {} pending entries!!! Dropping!!!!!", m_vFeedbacks.size());
m_vFeedbacks = {m_vFeedbacks.begin() + 9000, m_vFeedbacks.end()};
if (m_feedbacks.size() > 10000 /* arbitrary number I chose as fitting */) {
LOGM(ERR, "FIXME: presentation has a feedback leak, and has grown to {} pending entries!!! Dropping!!!!!", m_feedbacks.size());
m_feedbacks = {m_feedbacks.begin() + 9000, m_feedbacks.end()};
}
std::erase_if(m_vFeedbacks, [](const auto& other) { return !other->surface || other->done; });
std::erase_if(m_vQueue, [pMonitor](const auto& other) { return !other->surface || other->pMonitor == pMonitor || !other->pMonitor || other->done; });
std::erase_if(m_feedbacks, [](const auto& other) { return !other->m_surface || other->m_done; });
std::erase_if(m_queue, [pMonitor](const auto& other) { return !other->m_surface || other->m_monitor == pMonitor || !other->m_monitor || other->m_done; });
}
void CPresentationProtocol::queueData(SP<CQueuedPresentationData> data) {
m_vQueue.emplace_back(data);
m_queue.emplace_back(data);
}

View File

@@ -19,13 +19,13 @@ class CQueuedPresentationData {
void presented();
void discarded();
bool done = false;
bool m_done = false;
private:
bool wasPresented = false;
bool zeroCopy = false;
PHLMONITORREF pMonitor;
WP<CWLSurfaceResource> surface;
bool m_wasPresented = false;
bool m_zeroCopy = false;
PHLMONITORREF m_monitor;
WP<CWLSurfaceResource> m_surface;
friend class CPresentationFeedback;
friend class CPresentationProtocol;
@@ -40,9 +40,9 @@ class CPresentationFeedback {
void sendQueued(SP<CQueuedPresentationData> data, const Time::steady_tp& when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags);
private:
SP<CWpPresentationFeedback> resource;
WP<CWLSurfaceResource> surface;
bool done = false;
SP<CWpPresentationFeedback> m_resource;
WP<CWLSurfaceResource> m_surface;
bool m_done = false;
friend class CPresentationProtocol;
};
@@ -62,9 +62,9 @@ class CPresentationProtocol : public IWaylandProtocol {
void onGetFeedback(CWpPresentation* pMgr, wl_resource* surf, uint32_t id);
//
std::vector<UP<CWpPresentation>> m_vManagers;
std::vector<SP<CPresentationFeedback>> m_vFeedbacks;
std::vector<SP<CQueuedPresentationData>> m_vQueue;
std::vector<UP<CWpPresentation>> m_managers;
std::vector<SP<CPresentationFeedback>> m_feedbacks;
std::vector<SP<CQueuedPresentationData>> m_queue;
friend class CPresentationFeedback;
};

View File

@@ -5,60 +5,60 @@
#include "../config/ConfigValue.hpp"
using namespace Hyprutils::OS;
CPrimarySelectionOffer::CPrimarySelectionOffer(SP<CZwpPrimarySelectionOfferV1> resource_, SP<IDataSource> source_) : source(source_), resource(resource_) {
CPrimarySelectionOffer::CPrimarySelectionOffer(SP<CZwpPrimarySelectionOfferV1> resource_, SP<IDataSource> source_) : m_source(source_), m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setDestroy([this](CZwpPrimarySelectionOfferV1* r) { PROTO::primarySelection->destroyResource(this); });
resource->setOnDestroy([this](CZwpPrimarySelectionOfferV1* r) { PROTO::primarySelection->destroyResource(this); });
m_resource->setDestroy([this](CZwpPrimarySelectionOfferV1* r) { PROTO::primarySelection->destroyResource(this); });
m_resource->setOnDestroy([this](CZwpPrimarySelectionOfferV1* r) { PROTO::primarySelection->destroyResource(this); });
resource->setReceive([this](CZwpPrimarySelectionOfferV1* r, const char* mime, int32_t fd) {
m_resource->setReceive([this](CZwpPrimarySelectionOfferV1* r, const char* mime, int32_t fd) {
CFileDescriptor sendFd{fd};
if (!source) {
if (!m_source) {
LOGM(WARN, "Possible bug: Receive on an offer w/o a source");
return;
}
if (dead) {
if (m_dead) {
LOGM(WARN, "Possible bug: Receive on an offer that's dead");
return;
}
LOGM(LOG, "Offer {:x} asks to send data from source {:x}", (uintptr_t)this, (uintptr_t)source.get());
LOGM(LOG, "Offer {:x} asks to send data from source {:x}", (uintptr_t)this, (uintptr_t)m_source.get());
source->send(mime, std::move(sendFd));
m_source->send(mime, std::move(sendFd));
});
}
bool CPrimarySelectionOffer::good() {
return resource->resource();
return m_resource->resource();
}
void CPrimarySelectionOffer::sendData() {
if UNLIKELY (!source)
if UNLIKELY (!m_source)
return;
for (auto const& m : source->mimes()) {
resource->sendOffer(m.c_str());
for (auto const& m : m_source->mimes()) {
m_resource->sendOffer(m.c_str());
}
}
CPrimarySelectionSource::CPrimarySelectionSource(SP<CZwpPrimarySelectionSourceV1> resource_, SP<CPrimarySelectionDevice> device_) : device(device_), resource(resource_) {
CPrimarySelectionSource::CPrimarySelectionSource(SP<CZwpPrimarySelectionSourceV1> resource_, SP<CPrimarySelectionDevice> device_) : m_device(device_), m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setData(this);
m_resource->setData(this);
resource->setDestroy([this](CZwpPrimarySelectionSourceV1* r) {
m_resource->setDestroy([this](CZwpPrimarySelectionSourceV1* r) {
m_events.destroy.emit();
PROTO::primarySelection->destroyResource(this);
});
resource->setOnDestroy([this](CZwpPrimarySelectionSourceV1* r) {
m_resource->setOnDestroy([this](CZwpPrimarySelectionSourceV1* r) {
m_events.destroy.emit();
PROTO::primarySelection->destroyResource(this);
});
resource->setOffer([this](CZwpPrimarySelectionSourceV1* r, const char* mime) { mimeTypes.emplace_back(mime); });
m_resource->setOffer([this](CZwpPrimarySelectionSourceV1* r, const char* mime) { m_mimeTypes.emplace_back(mime); });
}
CPrimarySelectionSource::~CPrimarySelectionSource() {
@@ -67,51 +67,51 @@ CPrimarySelectionSource::~CPrimarySelectionSource() {
SP<CPrimarySelectionSource> CPrimarySelectionSource::fromResource(wl_resource* res) {
auto data = (CPrimarySelectionSource*)(((CZwpPrimarySelectionSourceV1*)wl_resource_get_user_data(res))->data());
return data ? data->self.lock() : nullptr;
return data ? data->m_self.lock() : nullptr;
}
bool CPrimarySelectionSource::good() {
return resource->resource();
return m_resource->resource();
}
std::vector<std::string> CPrimarySelectionSource::mimes() {
return mimeTypes;
return m_mimeTypes;
}
void CPrimarySelectionSource::send(const std::string& mime, CFileDescriptor fd) {
if (std::find(mimeTypes.begin(), mimeTypes.end(), mime) == mimeTypes.end()) {
if (std::find(m_mimeTypes.begin(), m_mimeTypes.end(), mime) == m_mimeTypes.end()) {
LOGM(ERR, "Compositor/App bug: CPrimarySelectionSource::sendAskSend with non-existent mime");
return;
}
resource->sendSend(mime.c_str(), fd.get());
m_resource->sendSend(mime.c_str(), fd.get());
}
void CPrimarySelectionSource::accepted(const std::string& mime) {
if (std::find(mimeTypes.begin(), mimeTypes.end(), mime) == mimeTypes.end())
if (std::find(m_mimeTypes.begin(), m_mimeTypes.end(), mime) == m_mimeTypes.end())
LOGM(ERR, "Compositor/App bug: CPrimarySelectionSource::sendAccepted with non-existent mime");
// primary sel has no accepted
}
void CPrimarySelectionSource::cancelled() {
resource->sendCancelled();
m_resource->sendCancelled();
}
void CPrimarySelectionSource::error(uint32_t code, const std::string& msg) {
resource->error(code, msg);
m_resource->error(code, msg);
}
CPrimarySelectionDevice::CPrimarySelectionDevice(SP<CZwpPrimarySelectionDeviceV1> resource_) : resource(resource_) {
CPrimarySelectionDevice::CPrimarySelectionDevice(SP<CZwpPrimarySelectionDeviceV1> resource_) : m_resource(resource_) {
if UNLIKELY (!good())
return;
pClient = resource->client();
m_client = m_resource->client();
resource->setDestroy([this](CZwpPrimarySelectionDeviceV1* r) { PROTO::primarySelection->destroyResource(this); });
resource->setOnDestroy([this](CZwpPrimarySelectionDeviceV1* r) { PROTO::primarySelection->destroyResource(this); });
m_resource->setDestroy([this](CZwpPrimarySelectionDeviceV1* r) { PROTO::primarySelection->destroyResource(this); });
m_resource->setOnDestroy([this](CZwpPrimarySelectionDeviceV1* r) { PROTO::primarySelection->destroyResource(this); });
resource->setSetSelection([](CZwpPrimarySelectionDeviceV1* r, wl_resource* sourceR, uint32_t serial) {
m_resource->setSetSelection([](CZwpPrimarySelectionDeviceV1* r, wl_resource* sourceR, uint32_t serial) {
static auto PPRIMARYSEL = CConfigValue<Hyprlang::INT>("misc:middle_click_paste");
if (!*PPRIMARYSEL) {
@@ -138,77 +138,77 @@ CPrimarySelectionDevice::CPrimarySelectionDevice(SP<CZwpPrimarySelectionDeviceV1
}
bool CPrimarySelectionDevice::good() {
return resource->resource();
return m_resource->resource();
}
wl_client* CPrimarySelectionDevice::client() {
return pClient;
return m_client;
}
void CPrimarySelectionDevice::sendDataOffer(SP<CPrimarySelectionOffer> offer) {
resource->sendDataOffer(offer->resource.get());
m_resource->sendDataOffer(offer->m_resource.get());
}
void CPrimarySelectionDevice::sendSelection(SP<CPrimarySelectionOffer> selection) {
if (!selection)
resource->sendSelectionRaw(nullptr);
m_resource->sendSelectionRaw(nullptr);
else
resource->sendSelection(selection->resource.get());
m_resource->sendSelection(selection->m_resource.get());
}
CPrimarySelectionManager::CPrimarySelectionManager(SP<CZwpPrimarySelectionDeviceManagerV1> resource_) : resource(resource_) {
CPrimarySelectionManager::CPrimarySelectionManager(SP<CZwpPrimarySelectionDeviceManagerV1> resource_) : m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setOnDestroy([this](CZwpPrimarySelectionDeviceManagerV1* r) { PROTO::primarySelection->destroyResource(this); });
m_resource->setOnDestroy([this](CZwpPrimarySelectionDeviceManagerV1* r) { PROTO::primarySelection->destroyResource(this); });
resource->setGetDevice([this](CZwpPrimarySelectionDeviceManagerV1* r, uint32_t id, wl_resource* seat) {
m_resource->setGetDevice([this](CZwpPrimarySelectionDeviceManagerV1* r, uint32_t id, wl_resource* seat) {
const auto RESOURCE =
PROTO::primarySelection->m_vDevices.emplace_back(makeShared<CPrimarySelectionDevice>(makeShared<CZwpPrimarySelectionDeviceV1>(r->client(), r->version(), id)));
PROTO::primarySelection->m_devices.emplace_back(makeShared<CPrimarySelectionDevice>(makeShared<CZwpPrimarySelectionDeviceV1>(r->client(), r->version(), id)));
if UNLIKELY (!RESOURCE->good()) {
r->noMemory();
PROTO::primarySelection->m_vDevices.pop_back();
PROTO::primarySelection->m_devices.pop_back();
return;
}
RESOURCE->self = RESOURCE;
device = RESOURCE;
RESOURCE->m_self = RESOURCE;
m_device = RESOURCE;
for (auto const& s : sources) {
for (auto const& s : m_sources) {
if (!s)
continue;
s->device = RESOURCE;
s->m_device = RESOURCE;
}
LOGM(LOG, "New primary selection data device bound at {:x}", (uintptr_t)RESOURCE.get());
});
resource->setCreateSource([this](CZwpPrimarySelectionDeviceManagerV1* r, uint32_t id) {
std::erase_if(sources, [](const auto& e) { return e.expired(); });
m_resource->setCreateSource([this](CZwpPrimarySelectionDeviceManagerV1* r, uint32_t id) {
std::erase_if(m_sources, [](const auto& e) { return e.expired(); });
const auto RESOURCE = PROTO::primarySelection->m_vSources.emplace_back(
makeShared<CPrimarySelectionSource>(makeShared<CZwpPrimarySelectionSourceV1>(r->client(), r->version(), id), device.lock()));
const auto RESOURCE = PROTO::primarySelection->m_sources.emplace_back(
makeShared<CPrimarySelectionSource>(makeShared<CZwpPrimarySelectionSourceV1>(r->client(), r->version(), id), m_device.lock()));
if UNLIKELY (!RESOURCE->good()) {
r->noMemory();
PROTO::primarySelection->m_vSources.pop_back();
PROTO::primarySelection->m_sources.pop_back();
return;
}
if (!device)
if (!m_device)
LOGM(WARN, "New data source before a device was created");
RESOURCE->self = RESOURCE;
RESOURCE->m_self = RESOURCE;
sources.emplace_back(RESOURCE);
m_sources.emplace_back(RESOURCE);
LOGM(LOG, "New primary selection data source bound at {:x}", (uintptr_t)RESOURCE.get());
});
}
bool CPrimarySelectionManager::good() {
return resource->resource();
return m_resource->resource();
}
CPrimarySelectionProtocol::CPrimarySelectionProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -216,35 +216,35 @@ CPrimarySelectionProtocol::CPrimarySelectionProtocol(const wl_interface* iface,
}
void CPrimarySelectionProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeShared<CPrimarySelectionManager>(makeShared<CZwpPrimarySelectionDeviceManagerV1>(client, ver, id)));
const auto RESOURCE = m_managers.emplace_back(makeShared<CPrimarySelectionManager>(makeShared<CZwpPrimarySelectionDeviceManagerV1>(client, ver, id)));
if UNLIKELY (!RESOURCE->good()) {
wl_client_post_no_memory(client);
m_vManagers.pop_back();
m_managers.pop_back();
return;
}
LOGM(LOG, "New primary_seletion_manager at {:x}", (uintptr_t)RESOURCE.get());
// we need to do it here because protocols come before seatMgr
if (!listeners.onPointerFocusChange)
listeners.onPointerFocusChange = g_pSeatManager->m_events.pointerFocusChange.registerListener([this](std::any d) { this->onPointerFocus(); });
if (!m_listeners.onPointerFocusChange)
m_listeners.onPointerFocusChange = g_pSeatManager->m_events.pointerFocusChange.registerListener([this](std::any d) { this->onPointerFocus(); });
}
void CPrimarySelectionProtocol::destroyResource(CPrimarySelectionManager* resource) {
std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_managers, [&](const auto& other) { return other.get() == resource; });
}
void CPrimarySelectionProtocol::destroyResource(CPrimarySelectionSource* resource) {
std::erase_if(m_vSources, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_sources, [&](const auto& other) { return other.get() == resource; });
}
void CPrimarySelectionProtocol::destroyResource(CPrimarySelectionDevice* resource) {
std::erase_if(m_vDevices, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_devices, [&](const auto& other) { return other.get() == resource; });
}
void CPrimarySelectionProtocol::destroyResource(CPrimarySelectionOffer* resource) {
std::erase_if(m_vOffers, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_offers, [&](const auto& other) { return other.get() == resource; });
}
void CPrimarySelectionProtocol::sendSelectionToDevice(SP<CPrimarySelectionDevice> dev, SP<IDataSource> sel) {
@@ -254,11 +254,11 @@ void CPrimarySelectionProtocol::sendSelectionToDevice(SP<CPrimarySelectionDevice
}
const auto OFFER =
m_vOffers.emplace_back(makeShared<CPrimarySelectionOffer>(makeShared<CZwpPrimarySelectionOfferV1>(dev->resource->client(), dev->resource->version(), 0), sel));
m_offers.emplace_back(makeShared<CPrimarySelectionOffer>(makeShared<CZwpPrimarySelectionOfferV1>(dev->m_resource->client(), dev->m_resource->version(), 0), sel));
if (!OFFER->good()) {
dev->resource->noMemory();
m_vOffers.pop_back();
dev->m_resource->noMemory();
m_offers.pop_back();
return;
}
@@ -270,10 +270,10 @@ void CPrimarySelectionProtocol::sendSelectionToDevice(SP<CPrimarySelectionDevice
}
void CPrimarySelectionProtocol::setSelection(SP<IDataSource> source) {
for (auto const& o : m_vOffers) {
if (o->source && o->source->hasDnd())
for (auto const& o : m_offers) {
if (o->m_source && o->m_source->hasDnd())
continue;
o->dead = true;
o->m_dead = true;
}
if (!source) {
@@ -319,16 +319,16 @@ void CPrimarySelectionProtocol::updateSelection() {
}
void CPrimarySelectionProtocol::onPointerFocus() {
for (auto const& o : m_vOffers) {
o->dead = true;
for (auto const& o : m_offers) {
o->m_dead = true;
}
updateSelection();
}
SP<CPrimarySelectionDevice> CPrimarySelectionProtocol::dataDeviceForClient(wl_client* c) {
auto it = std::find_if(m_vDevices.begin(), m_vDevices.end(), [c](const auto& e) { return e->client() == c; });
if (it == m_vDevices.end())
auto it = std::find_if(m_devices.begin(), m_devices.end(), [c](const auto& e) { return e->client() == c; });
if (it == m_devices.end())
return nullptr;
return *it;
}

View File

@@ -19,12 +19,12 @@ class CPrimarySelectionOffer {
bool good();
void sendData();
bool dead = false;
bool m_dead = false;
WP<IDataSource> source;
WP<IDataSource> m_source;
private:
SP<CZwpPrimarySelectionOfferV1> resource;
SP<CZwpPrimarySelectionOfferV1> m_resource;
friend class CPrimarySelectionDevice;
};
@@ -44,12 +44,12 @@ class CPrimarySelectionSource : public IDataSource {
virtual void cancelled();
virtual void error(uint32_t code, const std::string& msg);
std::vector<std::string> mimeTypes;
WP<CPrimarySelectionSource> self;
WP<CPrimarySelectionDevice> device;
std::vector<std::string> m_mimeTypes;
WP<CPrimarySelectionSource> m_self;
WP<CPrimarySelectionDevice> m_device;
private:
SP<CZwpPrimarySelectionSourceV1> resource;
SP<CZwpPrimarySelectionSourceV1> m_resource;
};
class CPrimarySelectionDevice {
@@ -62,11 +62,11 @@ class CPrimarySelectionDevice {
void sendDataOffer(SP<CPrimarySelectionOffer> offer);
void sendSelection(SP<CPrimarySelectionOffer> selection);
WP<CPrimarySelectionDevice> self;
WP<CPrimarySelectionDevice> m_self;
private:
SP<CZwpPrimarySelectionDeviceV1> resource;
wl_client* pClient = nullptr;
SP<CZwpPrimarySelectionDeviceV1> m_resource;
wl_client* m_client = nullptr;
friend class CPrimarySelectionProtocol;
};
@@ -77,11 +77,11 @@ class CPrimarySelectionManager {
bool good();
WP<CPrimarySelectionDevice> device;
std::vector<WP<CPrimarySelectionSource>> sources;
WP<CPrimarySelectionDevice> m_device;
std::vector<WP<CPrimarySelectionSource>> m_sources;
private:
SP<CZwpPrimarySelectionDeviceManagerV1> resource;
SP<CZwpPrimarySelectionDeviceManagerV1> m_resource;
};
class CPrimarySelectionProtocol : public IWaylandProtocol {
@@ -97,10 +97,10 @@ class CPrimarySelectionProtocol : public IWaylandProtocol {
void destroyResource(CPrimarySelectionOffer* resource);
//
std::vector<SP<CPrimarySelectionManager>> m_vManagers;
std::vector<SP<CPrimarySelectionDevice>> m_vDevices;
std::vector<SP<CPrimarySelectionSource>> m_vSources;
std::vector<SP<CPrimarySelectionOffer>> m_vOffers;
std::vector<SP<CPrimarySelectionManager>> m_managers;
std::vector<SP<CPrimarySelectionDevice>> m_devices;
std::vector<SP<CPrimarySelectionSource>> m_sources;
std::vector<SP<CPrimarySelectionOffer>> m_offers;
//
void setSelection(SP<IDataSource> source);
@@ -119,7 +119,7 @@ class CPrimarySelectionProtocol : public IWaylandProtocol {
struct {
CHyprSignalListener onPointerFocusChange;
} listeners;
} m_listeners;
};
namespace PROTO {

View File

@@ -3,27 +3,27 @@
#include "core/Seat.hpp"
#include <algorithm>
CRelativePointer::CRelativePointer(SP<CZwpRelativePointerV1> resource_) : resource(resource_) {
CRelativePointer::CRelativePointer(SP<CZwpRelativePointerV1> resource_) : m_resource(resource_) {
if UNLIKELY (!resource_->resource())
return;
pClient = resource->client();
m_client = m_resource->client();
resource->setDestroy([this](CZwpRelativePointerV1* pMgr) { PROTO::relativePointer->destroyRelativePointer(this); });
resource->setOnDestroy([this](CZwpRelativePointerV1* pMgr) { PROTO::relativePointer->destroyRelativePointer(this); });
m_resource->setDestroy([this](CZwpRelativePointerV1* pMgr) { PROTO::relativePointer->destroyRelativePointer(this); });
m_resource->setOnDestroy([this](CZwpRelativePointerV1* pMgr) { PROTO::relativePointer->destroyRelativePointer(this); });
}
bool CRelativePointer::good() {
return resource->resource();
return m_resource->resource();
}
wl_client* CRelativePointer::client() {
return pClient;
return m_client;
}
void CRelativePointer::sendRelativeMotion(uint64_t time, const Vector2D& delta, const Vector2D& deltaUnaccel) {
resource->sendRelativeMotion(time >> 32, time & 0xFFFFFFFF, wl_fixed_from_double(delta.x), wl_fixed_from_double(delta.y), wl_fixed_from_double(deltaUnaccel.x),
wl_fixed_from_double(deltaUnaccel.y));
m_resource->sendRelativeMotion(time >> 32, time & 0xFFFFFFFF, wl_fixed_from_double(delta.x), wl_fixed_from_double(delta.y), wl_fixed_from_double(deltaUnaccel.x),
wl_fixed_from_double(deltaUnaccel.y));
}
CRelativePointerProtocol::CRelativePointerProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -31,7 +31,7 @@ CRelativePointerProtocol::CRelativePointerProtocol(const wl_interface* iface, co
}
void CRelativePointerProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeUnique<CZwpRelativePointerManagerV1>(client, ver, id)).get();
const auto RESOURCE = m_managers.emplace_back(makeUnique<CZwpRelativePointerManagerV1>(client, ver, id)).get();
RESOURCE->setOnDestroy([this](CZwpRelativePointerManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setDestroy([this](CZwpRelativePointerManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
@@ -39,20 +39,20 @@ void CRelativePointerProtocol::bindManager(wl_client* client, void* data, uint32
}
void CRelativePointerProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
std::erase_if(m_managers, [&](const auto& other) { return other->resource() == res; });
}
void CRelativePointerProtocol::destroyRelativePointer(CRelativePointer* pointer) {
std::erase_if(m_vRelativePointers, [&](const auto& other) { return other.get() == pointer; });
std::erase_if(m_relativePointers, [&](const auto& other) { return other.get() == pointer; });
}
void CRelativePointerProtocol::onGetRelativePointer(CZwpRelativePointerManagerV1* pMgr, uint32_t id, wl_resource* pointer) {
const auto CLIENT = pMgr->client();
const auto RESOURCE = m_vRelativePointers.emplace_back(makeUnique<CRelativePointer>(makeShared<CZwpRelativePointerV1>(CLIENT, pMgr->version(), id))).get();
const auto RESOURCE = m_relativePointers.emplace_back(makeUnique<CRelativePointer>(makeShared<CZwpRelativePointerV1>(CLIENT, pMgr->version(), id))).get();
if UNLIKELY (!RESOURCE->good()) {
pMgr->noMemory();
m_vRelativePointers.pop_back();
m_relativePointers.pop_back();
return;
}
}
@@ -64,7 +64,7 @@ void CRelativePointerProtocol::sendRelativeMotion(uint64_t time, const Vector2D&
const auto FOCUSED = g_pSeatManager->m_state.pointerFocusResource->client();
for (auto const& rp : m_vRelativePointers) {
for (auto const& rp : m_relativePointers) {
if (FOCUSED != rp->client())
continue;

View File

@@ -16,8 +16,8 @@ class CRelativePointer {
wl_client* client();
private:
SP<CZwpRelativePointerV1> resource;
wl_client* pClient = nullptr;
SP<CZwpRelativePointerV1> m_resource;
wl_client* m_client = nullptr;
};
class CRelativePointerProtocol : public IWaylandProtocol {
@@ -34,8 +34,8 @@ class CRelativePointerProtocol : public IWaylandProtocol {
void onGetRelativePointer(CZwpRelativePointerManagerV1* pMgr, uint32_t id, wl_resource* pointer);
//
std::vector<UP<CZwpRelativePointerManagerV1>> m_vManagers;
std::vector<UP<CRelativePointer>> m_vRelativePointers;
std::vector<UP<CZwpRelativePointerManagerV1>> m_managers;
std::vector<UP<CRelativePointer>> m_relativePointers;
friend class CRelativePointer;
};

View File

@@ -17,66 +17,66 @@
#include <algorithm>
#include <functional>
CScreencopyFrame::CScreencopyFrame(SP<CZwlrScreencopyFrameV1> resource_, int32_t overlay_cursor, wl_resource* output, CBox box_) : resource(resource_) {
CScreencopyFrame::CScreencopyFrame(SP<CZwlrScreencopyFrameV1> resource_, int32_t overlay_cursor, wl_resource* output, CBox box_) : m_resource(resource_) {
if UNLIKELY (!good())
return;
overlayCursor = !!overlay_cursor;
pMonitor = CWLOutputResource::fromResource(output)->m_monitor;
m_overlayCursor = !!overlay_cursor;
m_monitor = CWLOutputResource::fromResource(output)->m_monitor;
if (!pMonitor) {
if (!m_monitor) {
LOGM(ERR, "Client requested sharing of a monitor that doesnt exist");
resource->sendFailed();
m_resource->sendFailed();
return;
}
resource->setOnDestroy([this](CZwlrScreencopyFrameV1* pMgr) { PROTO::screencopy->destroyResource(this); });
resource->setDestroy([this](CZwlrScreencopyFrameV1* pFrame) { PROTO::screencopy->destroyResource(this); });
resource->setCopy([this](CZwlrScreencopyFrameV1* pFrame, wl_resource* res) { this->copy(pFrame, res); });
resource->setCopyWithDamage([this](CZwlrScreencopyFrameV1* pFrame, wl_resource* res) {
withDamage = true;
m_resource->setOnDestroy([this](CZwlrScreencopyFrameV1* pMgr) { PROTO::screencopy->destroyResource(this); });
m_resource->setDestroy([this](CZwlrScreencopyFrameV1* pFrame) { PROTO::screencopy->destroyResource(this); });
m_resource->setCopy([this](CZwlrScreencopyFrameV1* pFrame, wl_resource* res) { this->copy(pFrame, res); });
m_resource->setCopyWithDamage([this](CZwlrScreencopyFrameV1* pFrame, wl_resource* res) {
m_withDamage = true;
this->copy(pFrame, res);
});
g_pHyprRenderer->makeEGLCurrent();
shmFormat = g_pHyprOpenGL->getPreferredReadFormat(pMonitor.lock());
if (shmFormat == DRM_FORMAT_INVALID) {
m_shmFormat = g_pHyprOpenGL->getPreferredReadFormat(m_monitor.lock());
if (m_shmFormat == DRM_FORMAT_INVALID) {
LOGM(ERR, "No format supported by renderer in capture output");
resource->sendFailed();
m_resource->sendFailed();
return;
}
// TODO: hack, we can't bit flip so we'll format flip heh, GL_BGRA_EXT wont work here
if (shmFormat == DRM_FORMAT_XRGB2101010 || shmFormat == DRM_FORMAT_ARGB2101010)
shmFormat = DRM_FORMAT_XBGR2101010;
if (m_shmFormat == DRM_FORMAT_XRGB2101010 || m_shmFormat == DRM_FORMAT_ARGB2101010)
m_shmFormat = DRM_FORMAT_XBGR2101010;
const auto PSHMINFO = NFormatUtils::getPixelFormatFromDRM(shmFormat);
const auto PSHMINFO = NFormatUtils::getPixelFormatFromDRM(m_shmFormat);
if (!PSHMINFO) {
LOGM(ERR, "No pixel format supported by renderer in capture output");
resource->sendFailed();
m_resource->sendFailed();
return;
}
dmabufFormat = pMonitor->m_output->state->state().drmFormat;
m_dmabufFormat = m_monitor->m_output->state->state().drmFormat;
if (box_.width == 0 && box_.height == 0)
box = {0, 0, (int)(pMonitor->m_size.x), (int)(pMonitor->m_size.y)};
m_box = {0, 0, (int)(m_monitor->m_size.x), (int)(m_monitor->m_size.y)};
else {
box = box_;
m_box = box_;
}
box.transform(wlTransformToHyprutils(pMonitor->m_transform), pMonitor->m_transformedSize.x, pMonitor->m_transformedSize.y).scale(pMonitor->m_scale).round();
m_box.transform(wlTransformToHyprutils(m_monitor->m_transform), m_monitor->m_transformedSize.x, m_monitor->m_transformedSize.y).scale(m_monitor->m_scale).round();
shmStride = NFormatUtils::minStride(PSHMINFO, box.w);
m_shmStride = NFormatUtils::minStride(PSHMINFO, m_box.w);
resource->sendBuffer(NFormatUtils::drmToShm(shmFormat), box.width, box.height, shmStride);
m_resource->sendBuffer(NFormatUtils::drmToShm(m_shmFormat), m_box.width, m_box.height, m_shmStride);
if (resource->version() >= 3) {
if LIKELY (dmabufFormat != DRM_FORMAT_INVALID)
resource->sendLinuxDmabuf(dmabufFormat, box.width, box.height);
if (m_resource->version() >= 3) {
if LIKELY (m_dmabufFormat != DRM_FORMAT_INVALID)
m_resource->sendLinuxDmabuf(m_dmabufFormat, m_box.width, m_box.height);
resource->sendBufferDone();
m_resource->sendBufferDone();
}
}
@@ -86,137 +86,137 @@ void CScreencopyFrame::copy(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer_
return;
}
if UNLIKELY (!g_pCompositor->monitorExists(pMonitor.lock())) {
if UNLIKELY (!g_pCompositor->monitorExists(m_monitor.lock())) {
LOGM(ERR, "Client requested sharing of a monitor that is gone");
resource->sendFailed();
m_resource->sendFailed();
return;
}
const auto PBUFFER = CWLBufferResource::fromResource(buffer_);
if UNLIKELY (!PBUFFER) {
LOGM(ERR, "Invalid buffer in {:x}", (uintptr_t)this);
resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer");
m_resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer");
PROTO::screencopy->destroyResource(this);
return;
}
if UNLIKELY (PBUFFER->m_buffer->size != box.size()) {
if UNLIKELY (PBUFFER->m_buffer->size != m_box.size()) {
LOGM(ERR, "Invalid dimensions in {:x}", (uintptr_t)this);
resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer dimensions");
m_resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer dimensions");
PROTO::screencopy->destroyResource(this);
return;
}
if UNLIKELY (buffer) {
if UNLIKELY (m_buffer) {
LOGM(ERR, "Buffer used in {:x}", (uintptr_t)this);
resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_ALREADY_USED, "frame already used");
m_resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_ALREADY_USED, "frame already used");
PROTO::screencopy->destroyResource(this);
return;
}
if (auto attrs = PBUFFER->m_buffer->dmabuf(); attrs.success) {
bufferDMA = true;
m_bufferDMA = true;
if (attrs.format != dmabufFormat) {
if (attrs.format != m_dmabufFormat) {
LOGM(ERR, "Invalid buffer dma format in {:x}", (uintptr_t)pFrame);
resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
m_resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
PROTO::screencopy->destroyResource(this);
return;
}
} else if (auto attrs = PBUFFER->m_buffer->shm(); attrs.success) {
if (attrs.format != shmFormat) {
if (attrs.format != m_shmFormat) {
LOGM(ERR, "Invalid buffer shm format in {:x}", (uintptr_t)pFrame);
resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
m_resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
PROTO::screencopy->destroyResource(this);
return;
} else if ((int)attrs.stride != shmStride) {
} else if ((int)attrs.stride != m_shmStride) {
LOGM(ERR, "Invalid buffer shm stride in {:x}", (uintptr_t)pFrame);
resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer stride");
m_resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer stride");
PROTO::screencopy->destroyResource(this);
return;
}
} else {
LOGM(ERR, "Invalid buffer type in {:x}", (uintptr_t)pFrame);
resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer type");
m_resource->error(ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer type");
PROTO::screencopy->destroyResource(this);
return;
}
buffer = CHLBufferReference(PBUFFER->m_buffer.lock());
m_buffer = CHLBufferReference(PBUFFER->m_buffer.lock());
PROTO::screencopy->m_vFramesAwaitingWrite.emplace_back(self);
PROTO::screencopy->m_framesAwaitingWrite.emplace_back(m_self);
g_pHyprRenderer->m_bDirectScanoutBlocked = true;
if (!withDamage)
g_pHyprRenderer->damageMonitor(pMonitor.lock());
if (!m_withDamage)
g_pHyprRenderer->damageMonitor(m_monitor.lock());
}
void CScreencopyFrame::share() {
if (!buffer || !pMonitor)
if (!m_buffer || !m_monitor)
return;
const auto NOW = Time::steadyNow();
auto callback = [this, NOW, weak = self](bool success) {
auto callback = [this, NOW, weak = m_self](bool success) {
if (weak.expired())
return;
if (!success) {
LOGM(ERR, "{} copy failed in {:x}", bufferDMA ? "Dmabuf" : "Shm", (uintptr_t)this);
resource->sendFailed();
LOGM(ERR, "{} copy failed in {:x}", m_bufferDMA ? "Dmabuf" : "Shm", (uintptr_t)this);
m_resource->sendFailed();
return;
}
resource->sendFlags((zwlrScreencopyFrameV1Flags)0);
if (withDamage) {
m_resource->sendFlags((zwlrScreencopyFrameV1Flags)0);
if (m_withDamage) {
// TODO: add a damage ring for this.
resource->sendDamage(0, 0, buffer->size.x, buffer->size.y);
m_resource->sendDamage(0, 0, m_buffer->size.x, m_buffer->size.y);
}
const auto [sec, nsec] = Time::secNsec(NOW);
uint32_t tvSecHi = (sizeof(sec) > 4) ? sec >> 32 : 0;
uint32_t tvSecLo = sec & 0xFFFFFFFF;
resource->sendReady(tvSecHi, tvSecLo, nsec);
m_resource->sendReady(tvSecHi, tvSecLo, nsec);
};
if (bufferDMA)
if (m_bufferDMA)
copyDmabuf(callback);
else
callback(copyShm());
}
void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(resource->client(), PERMISSION_TYPE_SCREENCOPY);
auto TEXTURE = makeShared<CTexture>(pMonitor->m_output->state->state().buffer);
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer);
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
if (!g_pHyprRenderer->beginRender(pMonitor.lock(), fakeDamage, RENDER_MODE_TO_BUFFER, buffer.m_buffer, nullptr, true)) {
if (!g_pHyprRenderer->beginRender(m_monitor.lock(), fakeDamage, RENDER_MODE_TO_BUFFER, m_buffer.m_buffer, nullptr, true)) {
LOGM(ERR, "Can't copy: failed to begin rendering to dma frame");
callback(false);
return;
}
if (PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW) {
CBox monbox = CBox{0, 0, pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y}
.translate({-box.x, -box.y}) // vvvv kinda ass-backwards but that's how I designed the renderer... sigh.
.transform(wlTransformToHyprutils(invertTransform(pMonitor->m_transform)), pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y);
CBox monbox = CBox{0, 0, m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y}
.translate({-m_box.x, -m_box.y}) // vvvv kinda ass-backwards but that's how I designed the renderer... sigh.
.transform(wlTransformToHyprutils(invertTransform(m_monitor->m_transform)), m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y);
g_pHyprOpenGL->setMonitorTransformEnabled(true);
g_pHyprOpenGL->setRenderModifEnabled(false);
g_pHyprOpenGL->renderTexture(TEXTURE, monbox, 1);
g_pHyprOpenGL->setRenderModifEnabled(true);
g_pHyprOpenGL->setMonitorTransformEnabled(false);
if (overlayCursor)
g_pPointerManager->renderSoftwareCursorsFor(pMonitor.lock(), Time::steadyNow(), fakeDamage,
g_pInputManager->getMouseCoordsInternal() - pMonitor->m_position - box.pos(), true);
if (m_overlayCursor)
g_pPointerManager->renderSoftwareCursorsFor(m_monitor.lock(), Time::steadyNow(), fakeDamage,
g_pInputManager->getMouseCoordsInternal() - m_monitor->m_position - m_box.pos(), true);
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
g_pHyprOpenGL->clear(Colors::BLACK);
else {
g_pHyprOpenGL->clear(Colors::BLACK);
CBox texbox =
CBox{pMonitor->m_transformedSize / 2.F, g_pHyprOpenGL->m_pScreencopyDeniedTexture->m_vSize}.translate(-g_pHyprOpenGL->m_pScreencopyDeniedTexture->m_vSize / 2.F);
CBox{m_monitor->m_transformedSize / 2.F, g_pHyprOpenGL->m_pScreencopyDeniedTexture->m_vSize}.translate(-g_pHyprOpenGL->m_pScreencopyDeniedTexture->m_vSize / 2.F);
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_pScreencopyDeniedTexture, texbox, 1);
}
@@ -229,40 +229,40 @@ void CScreencopyFrame::copyDmabuf(std::function<void(bool)> callback) {
}
bool CScreencopyFrame::copyShm() {
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(resource->client(), PERMISSION_TYPE_SCREENCOPY);
auto TEXTURE = makeShared<CTexture>(pMonitor->m_output->state->state().buffer);
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer);
auto shm = buffer->shm();
auto [pixelData, fmt, bufLen] = buffer->beginDataPtr(0); // no need for end, cuz it's shm
auto shm = m_buffer->shm();
auto [pixelData, fmt, bufLen] = m_buffer->beginDataPtr(0); // no need for end, cuz it's shm
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
g_pHyprRenderer->makeEGLCurrent();
CFramebuffer fb;
fb.alloc(box.w, box.h, pMonitor->m_output->state->state().drmFormat);
fb.alloc(m_box.w, m_box.h, m_monitor->m_output->state->state().drmFormat);
if (!g_pHyprRenderer->beginRender(pMonitor.lock(), fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, &fb, true)) {
if (!g_pHyprRenderer->beginRender(m_monitor.lock(), fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, &fb, true)) {
LOGM(ERR, "Can't copy: failed to begin rendering");
return false;
}
if (PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW) {
CBox monbox = CBox{0, 0, pMonitor->m_transformedSize.x, pMonitor->m_transformedSize.y}.translate({-box.x, -box.y});
CBox monbox = CBox{0, 0, m_monitor->m_transformedSize.x, m_monitor->m_transformedSize.y}.translate({-m_box.x, -m_box.y});
g_pHyprOpenGL->setMonitorTransformEnabled(true);
g_pHyprOpenGL->setRenderModifEnabled(false);
g_pHyprOpenGL->renderTexture(TEXTURE, monbox, 1);
g_pHyprOpenGL->setRenderModifEnabled(true);
g_pHyprOpenGL->setMonitorTransformEnabled(false);
if (overlayCursor)
g_pPointerManager->renderSoftwareCursorsFor(pMonitor.lock(), Time::steadyNow(), fakeDamage,
g_pInputManager->getMouseCoordsInternal() - pMonitor->m_position - box.pos(), true);
if (m_overlayCursor)
g_pPointerManager->renderSoftwareCursorsFor(m_monitor.lock(), Time::steadyNow(), fakeDamage,
g_pInputManager->getMouseCoordsInternal() - m_monitor->m_position - m_box.pos(), true);
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
g_pHyprOpenGL->clear(Colors::BLACK);
else {
g_pHyprOpenGL->clear(Colors::BLACK);
CBox texbox =
CBox{pMonitor->m_transformedSize / 2.F, g_pHyprOpenGL->m_pScreencopyDeniedTexture->m_vSize}.translate(-g_pHyprOpenGL->m_pScreencopyDeniedTexture->m_vSize / 2.F);
CBox{m_monitor->m_transformedSize / 2.F, g_pHyprOpenGL->m_pScreencopyDeniedTexture->m_vSize}.translate(-g_pHyprOpenGL->m_pScreencopyDeniedTexture->m_vSize / 2.F);
g_pHyprOpenGL->renderTexture(g_pHyprOpenGL->m_pScreencopyDeniedTexture, texbox, 1);
}
@@ -285,22 +285,22 @@ bool CScreencopyFrame::copyShm() {
g_pHyprRenderer->endRender();
g_pHyprRenderer->makeEGLCurrent();
g_pHyprOpenGL->m_RenderData.pMonitor = pMonitor;
g_pHyprOpenGL->m_RenderData.pMonitor = m_monitor;
fb.bind();
glPixelStorei(GL_PACK_ALIGNMENT, 1);
const auto drmFmt = NFormatUtils::getPixelFormatFromDRM(shm.format);
uint32_t packStride = NFormatUtils::minStride(drmFmt, box.w);
uint32_t packStride = NFormatUtils::minStride(drmFmt, m_box.w);
// This could be optimized by using a pixel buffer object to make this async,
// but really clients should just use a dma buffer anyways.
if (packStride == (uint32_t)shm.stride) {
glReadPixels(0, 0, box.w, box.h, glFormat, PFORMAT->glType, pixelData);
glReadPixels(0, 0, m_box.w, m_box.h, glFormat, PFORMAT->glType, pixelData);
} else {
for (size_t i = 0; i < box.h; ++i) {
for (size_t i = 0; i < m_box.h; ++i) {
uint32_t y = i;
glReadPixels(0, y, box.w, 1, glFormat, PFORMAT->glType, ((unsigned char*)pixelData) + i * shm.stride);
glReadPixels(0, y, m_box.w, 1, glFormat, PFORMAT->glType, ((unsigned char*)pixelData) + i * shm.stride);
}
}
@@ -318,68 +318,68 @@ bool CScreencopyFrame::copyShm() {
}
bool CScreencopyFrame::good() {
return resource->resource();
return m_resource->resource();
}
CScreencopyClient::~CScreencopyClient() {
g_pHookSystem->unhook(tickCallback);
g_pHookSystem->unhook(m_tickCallback);
}
CScreencopyClient::CScreencopyClient(SP<CZwlrScreencopyManagerV1> resource_) : resource(resource_) {
CScreencopyClient::CScreencopyClient(SP<CZwlrScreencopyManagerV1> resource_) : m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setDestroy([this](CZwlrScreencopyManagerV1* pMgr) { PROTO::screencopy->destroyResource(this); });
resource->setOnDestroy([this](CZwlrScreencopyManagerV1* pMgr) { PROTO::screencopy->destroyResource(this); });
resource->setCaptureOutput(
m_resource->setDestroy([this](CZwlrScreencopyManagerV1* pMgr) { PROTO::screencopy->destroyResource(this); });
m_resource->setOnDestroy([this](CZwlrScreencopyManagerV1* pMgr) { PROTO::screencopy->destroyResource(this); });
m_resource->setCaptureOutput(
[this](CZwlrScreencopyManagerV1* pMgr, uint32_t frame, int32_t overlayCursor, wl_resource* output) { this->captureOutput(frame, overlayCursor, output, {}); });
resource->setCaptureOutputRegion([this](CZwlrScreencopyManagerV1* pMgr, uint32_t frame, int32_t overlayCursor, wl_resource* output, int32_t x, int32_t y, int32_t w,
int32_t h) { this->captureOutput(frame, overlayCursor, output, {x, y, w, h}); });
m_resource->setCaptureOutputRegion([this](CZwlrScreencopyManagerV1* pMgr, uint32_t frame, int32_t overlayCursor, wl_resource* output, int32_t x, int32_t y, int32_t w,
int32_t h) { this->captureOutput(frame, overlayCursor, output, {x, y, w, h}); });
lastMeasure.reset();
lastFrame.reset();
tickCallback = g_pHookSystem->hookDynamic("tick", [&](void* self, SCallbackInfo& info, std::any data) { onTick(); });
m_lastMeasure.reset();
m_lastFrame.reset();
m_tickCallback = g_pHookSystem->hookDynamic("tick", [&](void* self, SCallbackInfo& info, std::any data) { onTick(); });
}
void CScreencopyClient::captureOutput(uint32_t frame, int32_t overlayCursor_, wl_resource* output, CBox box) {
const auto FRAME = PROTO::screencopy->m_vFrames.emplace_back(
makeShared<CScreencopyFrame>(makeShared<CZwlrScreencopyFrameV1>(resource->client(), resource->version(), frame), overlayCursor_, output, box));
const auto FRAME = PROTO::screencopy->m_frames.emplace_back(
makeShared<CScreencopyFrame>(makeShared<CZwlrScreencopyFrameV1>(m_resource->client(), m_resource->version(), frame), overlayCursor_, output, box));
if (!FRAME->good()) {
LOGM(ERR, "Couldn't alloc frame for sharing! (no memory)");
resource->noMemory();
m_resource->noMemory();
PROTO::screencopy->destroyResource(FRAME.get());
return;
}
FRAME->self = FRAME;
FRAME->client = self;
FRAME->m_self = FRAME;
FRAME->m_client = m_self;
}
void CScreencopyClient::onTick() {
if (lastMeasure.getMillis() < 500)
if (m_lastMeasure.getMillis() < 500)
return;
framesInLastHalfSecond = frameCounter;
frameCounter = 0;
lastMeasure.reset();
m_framesInLastHalfSecond = m_frameCounter;
m_frameCounter = 0;
m_lastMeasure.reset();
const auto LASTFRAMEDELTA = lastFrame.getMillis() / 1000.0;
const bool FRAMEAWAITING = std::ranges::any_of(PROTO::screencopy->m_vFrames, [&](const auto& frame) { return frame->client.get() == this; });
const auto LASTFRAMEDELTA = m_lastFrame.getMillis() / 1000.0;
const bool FRAMEAWAITING = std::ranges::any_of(PROTO::screencopy->m_frames, [&](const auto& frame) { return frame->m_client.get() == this; });
if (framesInLastHalfSecond > 3 && !sentScreencast) {
EMIT_HOOK_EVENT("screencast", (std::vector<uint64_t>{1, (uint64_t)framesInLastHalfSecond, (uint64_t)clientOwner}));
g_pEventManager->postEvent(SHyprIPCEvent{"screencast", "1," + std::to_string(clientOwner)});
sentScreencast = true;
} else if (framesInLastHalfSecond < 4 && sentScreencast && LASTFRAMEDELTA > 1.0 && !FRAMEAWAITING) {
EMIT_HOOK_EVENT("screencast", (std::vector<uint64_t>{0, (uint64_t)framesInLastHalfSecond, (uint64_t)clientOwner}));
g_pEventManager->postEvent(SHyprIPCEvent{"screencast", "0," + std::to_string(clientOwner)});
sentScreencast = false;
if (m_framesInLastHalfSecond > 3 && !m_sentScreencast) {
EMIT_HOOK_EVENT("screencast", (std::vector<uint64_t>{1, (uint64_t)m_framesInLastHalfSecond, (uint64_t)m_clientOwner}));
g_pEventManager->postEvent(SHyprIPCEvent{"screencast", "1," + std::to_string(m_clientOwner)});
m_sentScreencast = true;
} else if (m_framesInLastHalfSecond < 4 && m_sentScreencast && LASTFRAMEDELTA > 1.0 && !FRAMEAWAITING) {
EMIT_HOOK_EVENT("screencast", (std::vector<uint64_t>{0, (uint64_t)m_framesInLastHalfSecond, (uint64_t)m_clientOwner}));
g_pEventManager->postEvent(SHyprIPCEvent{"screencast", "0," + std::to_string(m_clientOwner)});
m_sentScreencast = false;
}
}
bool CScreencopyClient::good() {
return resource->resource();
return m_resource->resource();
}
CScreencopyProtocol::CScreencopyProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -387,71 +387,71 @@ CScreencopyProtocol::CScreencopyProtocol(const wl_interface* iface, const int& v
}
void CScreencopyProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto CLIENT = m_vClients.emplace_back(makeShared<CScreencopyClient>(makeShared<CZwlrScreencopyManagerV1>(client, ver, id)));
const auto CLIENT = m_clients.emplace_back(makeShared<CScreencopyClient>(makeShared<CZwlrScreencopyManagerV1>(client, ver, id)));
if (!CLIENT->good()) {
LOGM(LOG, "Failed to bind client! (out of memory)");
CLIENT->resource->noMemory();
m_vClients.pop_back();
CLIENT->m_resource->noMemory();
m_clients.pop_back();
return;
}
CLIENT->self = CLIENT;
CLIENT->m_self = CLIENT;
LOGM(LOG, "Bound client successfully!");
}
void CScreencopyProtocol::destroyResource(CScreencopyClient* client) {
std::erase_if(m_vClients, [&](const auto& other) { return other.get() == client; });
std::erase_if(m_vFrames, [&](const auto& other) { return other->client.get() == client; });
std::erase_if(m_vFramesAwaitingWrite, [&](const auto& other) { return !other || other->client.get() == client; });
std::erase_if(m_clients, [&](const auto& other) { return other.get() == client; });
std::erase_if(m_frames, [&](const auto& other) { return other->m_client.get() == client; });
std::erase_if(m_framesAwaitingWrite, [&](const auto& other) { return !other || other->m_client.get() == client; });
}
void CScreencopyProtocol::destroyResource(CScreencopyFrame* frame) {
std::erase_if(m_vFrames, [&](const auto& other) { return other.get() == frame; });
std::erase_if(m_vFramesAwaitingWrite, [&](const auto& other) { return !other || other.get() == frame; });
std::erase_if(m_frames, [&](const auto& other) { return other.get() == frame; });
std::erase_if(m_framesAwaitingWrite, [&](const auto& other) { return !other || other.get() == frame; });
}
void CScreencopyProtocol::onOutputCommit(PHLMONITOR pMonitor) {
if (m_vFramesAwaitingWrite.empty()) {
if (m_framesAwaitingWrite.empty()) {
g_pHyprRenderer->m_bDirectScanoutBlocked = false;
return; // nothing to share
}
std::vector<WP<CScreencopyFrame>> framesToRemove;
// reserve number of elements to avoid reallocations
framesToRemove.reserve(m_vFramesAwaitingWrite.size());
framesToRemove.reserve(m_framesAwaitingWrite.size());
// share frame if correct output
for (auto const& f : m_vFramesAwaitingWrite) {
for (auto const& f : m_framesAwaitingWrite) {
if (!f)
continue;
// check permissions
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(f->resource->client(), PERMISSION_TYPE_SCREENCOPY);
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(f->m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
continue; // pending an answer, don't do anything yet.
// otherwise share. If it's denied, it will be black.
if (!f->pMonitor || !f->buffer) {
if (!f->m_monitor || !f->m_buffer) {
framesToRemove.emplace_back(f);
continue;
}
if (f->pMonitor != pMonitor)
if (f->m_monitor != pMonitor)
continue;
f->share();
f->client->lastFrame.reset();
++f->client->frameCounter;
f->m_client->m_lastFrame.reset();
++f->m_client->m_frameCounter;
framesToRemove.emplace_back(f);
}
for (auto const& f : framesToRemove) {
std::erase(m_vFramesAwaitingWrite, f);
std::erase(m_framesAwaitingWrite, f);
}
}

View File

@@ -28,20 +28,20 @@ class CScreencopyClient {
bool good();
WP<CScreencopyClient> self;
eClientOwners clientOwner = CLIENT_SCREENCOPY;
WP<CScreencopyClient> m_self;
eClientOwners m_clientOwner = CLIENT_SCREENCOPY;
CTimer lastFrame;
int frameCounter = 0;
CTimer m_lastFrame;
int m_frameCounter = 0;
private:
SP<CZwlrScreencopyManagerV1> resource;
SP<CZwlrScreencopyManagerV1> m_resource;
int framesInLastHalfSecond = 0;
CTimer lastMeasure;
bool sentScreencast = false;
int m_framesInLastHalfSecond = 0;
CTimer m_lastMeasure;
bool m_sentScreencast = false;
SP<HOOK_CALLBACK_FN> tickCallback;
SP<HOOK_CALLBACK_FN> m_tickCallback;
void onTick();
void captureOutput(uint32_t frame, int32_t overlayCursor, wl_resource* output, CBox box);
@@ -55,23 +55,22 @@ class CScreencopyFrame {
bool good();
WP<CScreencopyFrame> self;
WP<CScreencopyClient> client;
WP<CScreencopyFrame> m_self;
WP<CScreencopyClient> m_client;
private:
SP<CZwlrScreencopyFrameV1> resource;
SP<CZwlrScreencopyFrameV1> m_resource;
PHLMONITORREF pMonitor;
bool overlayCursor = false;
bool withDamage = false;
bool lockedSWCursors = false;
PHLMONITORREF m_monitor;
bool m_overlayCursor = false;
bool m_withDamage = false;
CHLBufferReference buffer;
bool bufferDMA = false;
uint32_t shmFormat = 0;
uint32_t dmabufFormat = 0;
int shmStride = 0;
CBox box = {};
CHLBufferReference m_buffer;
bool m_bufferDMA = false;
uint32_t m_shmFormat = 0;
uint32_t m_dmabufFormat = 0;
int m_shmStride = 0;
CBox m_box = {};
void copy(CZwlrScreencopyFrameV1* pFrame, wl_resource* buffer);
void copyDmabuf(std::function<void(bool)> callback);
@@ -92,9 +91,9 @@ class CScreencopyProtocol : public IWaylandProtocol {
void onOutputCommit(PHLMONITOR pMonitor);
private:
std::vector<SP<CScreencopyFrame>> m_vFrames;
std::vector<WP<CScreencopyFrame>> m_vFramesAwaitingWrite;
std::vector<SP<CScreencopyClient>> m_vClients;
std::vector<SP<CScreencopyFrame>> m_frames;
std::vector<WP<CScreencopyFrame>> m_framesAwaitingWrite;
std::vector<SP<CScreencopyClient>> m_clients;
void shareAllFrames(PHLMONITOR pMonitor);
void shareFrame(CScreencopyFrame* frame);

View File

@@ -17,7 +17,7 @@ static int onCloseFdEvent(int fd, uint32_t mask, void* data) {
SP<CSecurityContextSandboxedClient> CSecurityContextSandboxedClient::create(CFileDescriptor clientFD_) {
auto p = SP<CSecurityContextSandboxedClient>(new CSecurityContextSandboxedClient(std::move(clientFD_)));
if (!p->client)
if (!p->m_client)
return nullptr;
return p;
}
@@ -28,95 +28,95 @@ static void onSecurityContextClientDestroy(wl_listener* l, void* d) {
client->onDestroy();
}
CSecurityContextSandboxedClient::CSecurityContextSandboxedClient(CFileDescriptor clientFD_) : clientFD(std::move(clientFD_)) {
client = wl_client_create(g_pCompositor->m_wlDisplay, clientFD.get());
if (!client)
CSecurityContextSandboxedClient::CSecurityContextSandboxedClient(CFileDescriptor clientFD_) : m_clientFD(std::move(clientFD_)) {
m_client = wl_client_create(g_pCompositor->m_wlDisplay, m_clientFD.get());
if (!m_client)
return;
wl_list_init(&destroyListener.listener.link);
destroyListener.listener.notify = ::onSecurityContextClientDestroy;
destroyListener.parent = this;
wl_client_add_destroy_late_listener(client, &destroyListener.listener);
wl_list_init(&m_destroyListener.listener.link);
m_destroyListener.listener.notify = ::onSecurityContextClientDestroy;
m_destroyListener.parent = this;
wl_client_add_destroy_late_listener(m_client, &m_destroyListener.listener);
}
CSecurityContextSandboxedClient::~CSecurityContextSandboxedClient() {
wl_list_remove(&destroyListener.listener.link);
wl_list_init(&destroyListener.listener.link);
wl_list_remove(&m_destroyListener.listener.link);
wl_list_init(&m_destroyListener.listener.link);
}
void CSecurityContextSandboxedClient::onDestroy() {
std::erase_if(PROTO::securityContext->m_vSandboxedClients, [this](const auto& e) { return e.get() == this; });
std::erase_if(PROTO::securityContext->m_sandboxedClients, [this](const auto& e) { return e.get() == this; });
}
CSecurityContext::CSecurityContext(SP<CWpSecurityContextV1> resource_, int listenFD_, int closeFD_) : listenFD(listenFD_), closeFD(closeFD_), resource(resource_) {
CSecurityContext::CSecurityContext(SP<CWpSecurityContextV1> resource_, int listenFD_, int closeFD_) : m_listenFD(listenFD_), m_closeFD(closeFD_), m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setDestroy([this](CWpSecurityContextV1* r) {
m_resource->setDestroy([this](CWpSecurityContextV1* r) {
LOGM(LOG, "security_context at 0x{:x}: resource destroyed, keeping context until fd hangup", (uintptr_t)this);
resource = nullptr;
m_resource = nullptr;
});
resource->setOnDestroy([this](CWpSecurityContextV1* r) {
m_resource->setOnDestroy([this](CWpSecurityContextV1* r) {
LOGM(LOG, "security_context at 0x{:x}: resource destroyed, keeping context until fd hangup", (uintptr_t)this);
resource = nullptr;
m_resource = nullptr;
});
LOGM(LOG, "New security_context at 0x{:x}", (uintptr_t)this);
resource->setSetSandboxEngine([this](CWpSecurityContextV1* r, const char* engine) {
if UNLIKELY (!sandboxEngine.empty()) {
m_resource->setSetSandboxEngine([this](CWpSecurityContextV1* r, const char* engine) {
if UNLIKELY (!m_sandboxEngine.empty()) {
r->error(WP_SECURITY_CONTEXT_V1_ERROR_ALREADY_SET, "Sandbox engine already set");
return;
}
if UNLIKELY (committed) {
if UNLIKELY (m_committed) {
r->error(WP_SECURITY_CONTEXT_V1_ERROR_ALREADY_USED, "Context already committed");
return;
}
sandboxEngine = engine ? engine : "(null)";
LOGM(LOG, "security_context at 0x{:x} sets engine to {}", (uintptr_t)this, sandboxEngine);
m_sandboxEngine = engine ? engine : "(null)";
LOGM(LOG, "security_context at 0x{:x} sets engine to {}", (uintptr_t)this, m_sandboxEngine);
});
resource->setSetAppId([this](CWpSecurityContextV1* r, const char* appid) {
if UNLIKELY (!appID.empty()) {
m_resource->setSetAppId([this](CWpSecurityContextV1* r, const char* appid) {
if UNLIKELY (!m_appID.empty()) {
r->error(WP_SECURITY_CONTEXT_V1_ERROR_ALREADY_SET, "Sandbox appid already set");
return;
}
if UNLIKELY (committed) {
if UNLIKELY (m_committed) {
r->error(WP_SECURITY_CONTEXT_V1_ERROR_ALREADY_USED, "Context already committed");
return;
}
appID = appid ? appid : "(null)";
LOGM(LOG, "security_context at 0x{:x} sets appid to {}", (uintptr_t)this, appID);
m_appID = appid ? appid : "(null)";
LOGM(LOG, "security_context at 0x{:x} sets appid to {}", (uintptr_t)this, m_appID);
});
resource->setSetInstanceId([this](CWpSecurityContextV1* r, const char* instance) {
if UNLIKELY (!instanceID.empty()) {
m_resource->setSetInstanceId([this](CWpSecurityContextV1* r, const char* instance) {
if UNLIKELY (!m_instanceID.empty()) {
r->error(WP_SECURITY_CONTEXT_V1_ERROR_ALREADY_SET, "Sandbox instance already set");
return;
}
if UNLIKELY (committed) {
if UNLIKELY (m_committed) {
r->error(WP_SECURITY_CONTEXT_V1_ERROR_ALREADY_USED, "Context already committed");
return;
}
instanceID = instance ? instance : "(null)";
LOGM(LOG, "security_context at 0x{:x} sets instance to {}", (uintptr_t)this, instanceID);
m_instanceID = instance ? instance : "(null)";
LOGM(LOG, "security_context at 0x{:x} sets instance to {}", (uintptr_t)this, m_instanceID);
});
resource->setCommit([this](CWpSecurityContextV1* r) {
committed = true;
m_resource->setCommit([this](CWpSecurityContextV1* r) {
m_committed = true;
LOGM(LOG, "security_context at 0x{:x} commits", (uintptr_t)this);
listenSource = wl_event_loop_add_fd(g_pCompositor->m_wlEventLoop, listenFD.get(), WL_EVENT_READABLE, ::onListenFdEvent, this);
closeSource = wl_event_loop_add_fd(g_pCompositor->m_wlEventLoop, closeFD.get(), 0, ::onCloseFdEvent, this);
m_listenSource = wl_event_loop_add_fd(g_pCompositor->m_wlEventLoop, m_listenFD.get(), WL_EVENT_READABLE, ::onListenFdEvent, this);
m_closeSource = wl_event_loop_add_fd(g_pCompositor->m_wlEventLoop, m_closeFD.get(), 0, ::onCloseFdEvent, this);
if (!listenSource || !closeSource) {
if (!m_listenSource || !m_closeSource) {
r->noMemory();
return;
}
@@ -124,14 +124,14 @@ CSecurityContext::CSecurityContext(SP<CWpSecurityContextV1> resource_, int liste
}
CSecurityContext::~CSecurityContext() {
if (listenSource)
wl_event_source_remove(listenSource);
if (closeSource)
wl_event_source_remove(closeSource);
if (m_listenSource)
wl_event_source_remove(m_listenSource);
if (m_closeSource)
wl_event_source_remove(m_closeSource);
}
bool CSecurityContext::good() {
return resource->resource();
return m_resource->resource();
}
void CSecurityContext::onListen(uint32_t mask) {
@@ -144,7 +144,7 @@ void CSecurityContext::onListen(uint32_t mask) {
if (!(mask & WL_EVENT_READABLE))
return;
CFileDescriptor clientFD{accept(listenFD.get(), nullptr, nullptr)};
CFileDescriptor clientFD{accept(m_listenFD.get(), nullptr, nullptr)};
if UNLIKELY (!clientFD.isValid()) {
LOGM(ERR, "security_context at 0x{:x} couldn't accept", (uintptr_t)this);
return;
@@ -156,9 +156,9 @@ void CSecurityContext::onListen(uint32_t mask) {
return;
}
PROTO::securityContext->m_vSandboxedClients.emplace_back(newClient);
PROTO::securityContext->m_sandboxedClients.emplace_back(newClient);
LOGM(LOG, "security_context at 0x{:x} got a new wl_client 0x{:x}", (uintptr_t)this, (uintptr_t)newClient->client);
LOGM(LOG, "security_context at 0x{:x} got a new wl_client 0x{:x}", (uintptr_t)this, (uintptr_t)newClient->m_client);
}
void CSecurityContext::onClose(uint32_t mask) {
@@ -168,27 +168,27 @@ void CSecurityContext::onClose(uint32_t mask) {
PROTO::securityContext->destroyContext(this);
}
CSecurityContextManagerResource::CSecurityContextManagerResource(SP<CWpSecurityContextManagerV1> resource_) : resource(resource_) {
CSecurityContextManagerResource::CSecurityContextManagerResource(SP<CWpSecurityContextManagerV1> resource_) : m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setDestroy([this](CWpSecurityContextManagerV1* r) { PROTO::securityContext->destroyResource(this); });
resource->setOnDestroy([this](CWpSecurityContextManagerV1* r) { PROTO::securityContext->destroyResource(this); });
m_resource->setDestroy([this](CWpSecurityContextManagerV1* r) { PROTO::securityContext->destroyResource(this); });
m_resource->setOnDestroy([this](CWpSecurityContextManagerV1* r) { PROTO::securityContext->destroyResource(this); });
resource->setCreateListener([](CWpSecurityContextManagerV1* r, uint32_t id, int32_t lfd, int32_t cfd) {
m_resource->setCreateListener([](CWpSecurityContextManagerV1* r, uint32_t id, int32_t lfd, int32_t cfd) {
const auto RESOURCE =
PROTO::securityContext->m_vContexts.emplace_back(makeShared<CSecurityContext>(makeShared<CWpSecurityContextV1>(r->client(), r->version(), id), lfd, cfd));
PROTO::securityContext->m_contexts.emplace_back(makeShared<CSecurityContext>(makeShared<CWpSecurityContextV1>(r->client(), r->version(), id), lfd, cfd));
if UNLIKELY (!RESOURCE->good()) {
r->noMemory();
PROTO::securityContext->m_vContexts.pop_back();
PROTO::securityContext->m_contexts.pop_back();
return;
}
});
}
bool CSecurityContextManagerResource::good() {
return resource->resource();
return m_resource->resource();
}
CSecurityContextProtocol::CSecurityContextProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -196,23 +196,23 @@ CSecurityContextProtocol::CSecurityContextProtocol(const wl_interface* iface, co
}
void CSecurityContextProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeShared<CSecurityContextManagerResource>(makeShared<CWpSecurityContextManagerV1>(client, ver, id)));
const auto RESOURCE = m_managers.emplace_back(makeShared<CSecurityContextManagerResource>(makeShared<CWpSecurityContextManagerV1>(client, ver, id)));
if UNLIKELY (!RESOURCE->good()) {
wl_client_post_no_memory(client);
m_vManagers.pop_back();
m_managers.pop_back();
return;
}
}
void CSecurityContextProtocol::destroyResource(CSecurityContextManagerResource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == res; });
std::erase_if(m_managers, [&](const auto& other) { return other.get() == res; });
}
void CSecurityContextProtocol::destroyContext(CSecurityContext* context) {
std::erase_if(m_vContexts, [&](const auto& other) { return other.get() == context; });
std::erase_if(m_contexts, [&](const auto& other) { return other.get() == context; });
}
bool CSecurityContextProtocol::isClientSandboxed(const wl_client* client) {
return std::find_if(m_vSandboxedClients.begin(), m_vSandboxedClients.end(), [client](const auto& e) { return e->client == client; }) != m_vSandboxedClients.end();
return std::find_if(m_sandboxedClients.begin(), m_sandboxedClients.end(), [client](const auto& e) { return e->m_client == client; }) != m_sandboxedClients.end();
}

View File

@@ -13,18 +13,23 @@ class CSecurityContext {
bool good();
std::string sandboxEngine, appID, instanceID;
Hyprutils::OS::CFileDescriptor listenFD, closeFD;
std::string m_sandboxEngine;
std::string m_appID;
std::string m_instanceID;
Hyprutils::OS::CFileDescriptor m_listenFD;
Hyprutils::OS::CFileDescriptor m_closeFD;
void onListen(uint32_t mask);
void onClose(uint32_t mask);
private:
SP<CWpSecurityContextV1> resource;
SP<CWpSecurityContextV1> m_resource;
wl_event_source * listenSource = nullptr, *closeSource = nullptr;
wl_event_source* m_listenSource = nullptr;
wl_event_source* m_closeSource = nullptr;
bool committed = false;
bool m_committed = false;
};
class CSecurityContextManagerResource {
@@ -34,7 +39,7 @@ class CSecurityContextManagerResource {
bool good();
private:
SP<CWpSecurityContextManagerV1> resource;
SP<CWpSecurityContextManagerV1> m_resource;
};
class CSecurityContextSandboxedClient;
@@ -50,13 +55,13 @@ class CSecurityContextSandboxedClient {
void onDestroy();
SCSecurityContextSandboxedClientDestroyWrapper destroyListener;
SCSecurityContextSandboxedClientDestroyWrapper m_destroyListener;
private:
CSecurityContextSandboxedClient(Hyprutils::OS::CFileDescriptor clientFD_);
wl_client* client = nullptr;
Hyprutils::OS::CFileDescriptor clientFD;
wl_client* m_client = nullptr;
Hyprutils::OS::CFileDescriptor m_clientFD;
friend class CSecurityContextProtocol;
friend class CSecurityContext;
@@ -76,9 +81,9 @@ class CSecurityContextProtocol : public IWaylandProtocol {
void destroyContext(CSecurityContext* context);
//
std::vector<SP<CSecurityContextManagerResource>> m_vManagers;
std::vector<SP<CSecurityContext>> m_vContexts;
std::vector<SP<CSecurityContextSandboxedClient>> m_vSandboxedClients;
std::vector<SP<CSecurityContextManagerResource>> m_managers;
std::vector<SP<CSecurityContext>> m_contexts;
std::vector<SP<CSecurityContextSandboxedClient>> m_sandboxedClients;
friend class CSecurityContextManagerResource;
friend class CSecurityContext;

View File

@@ -1,19 +1,19 @@
#include "ServerDecorationKDE.hpp"
#include "core/Compositor.hpp"
CServerDecorationKDE::CServerDecorationKDE(SP<COrgKdeKwinServerDecoration> resource_, SP<CWLSurfaceResource> surf) : resource(resource_) {
CServerDecorationKDE::CServerDecorationKDE(SP<COrgKdeKwinServerDecoration> resource_, SP<CWLSurfaceResource> surf) : m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setRelease([this](COrgKdeKwinServerDecoration* pMgr) { PROTO::serverDecorationKDE->destroyResource(this); });
resource->setOnDestroy([this](COrgKdeKwinServerDecoration* pMgr) { PROTO::serverDecorationKDE->destroyResource(this); });
m_resource->setRelease([this](COrgKdeKwinServerDecoration* pMgr) { PROTO::serverDecorationKDE->destroyResource(this); });
m_resource->setOnDestroy([this](COrgKdeKwinServerDecoration* pMgr) { PROTO::serverDecorationKDE->destroyResource(this); });
// we send this and ignore request_mode.
resource->sendMode(ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER);
m_resource->sendMode(ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER);
}
bool CServerDecorationKDE::good() {
return resource->resource();
return m_resource->resource();
}
CServerDecorationKDEProtocol::CServerDecorationKDEProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -21,7 +21,7 @@ CServerDecorationKDEProtocol::CServerDecorationKDEProtocol(const wl_interface* i
}
void CServerDecorationKDEProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeUnique<COrgKdeKwinServerDecorationManager>(client, ver, id)).get();
const auto RESOURCE = m_managers.emplace_back(makeUnique<COrgKdeKwinServerDecorationManager>(client, ver, id)).get();
RESOURCE->setOnDestroy([this](COrgKdeKwinServerDecorationManager* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setCreate([this](COrgKdeKwinServerDecorationManager* pMgr, uint32_t id, wl_resource* pointer) { this->createDecoration(pMgr, id, pointer); });
@@ -31,21 +31,21 @@ void CServerDecorationKDEProtocol::bindManager(wl_client* client, void* data, ui
}
void CServerDecorationKDEProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
std::erase_if(m_managers, [&](const auto& other) { return other->resource() == res; });
}
void CServerDecorationKDEProtocol::destroyResource(CServerDecorationKDE* hayperlaaaand) {
std::erase_if(m_vDecos, [&](const auto& other) { return other.get() == hayperlaaaand; });
std::erase_if(m_decos, [&](const auto& other) { return other.get() == hayperlaaaand; });
}
void CServerDecorationKDEProtocol::createDecoration(COrgKdeKwinServerDecorationManager* pMgr, uint32_t id, wl_resource* surf) {
const auto CLIENT = pMgr->client();
const auto RESOURCE =
m_vDecos.emplace_back(makeUnique<CServerDecorationKDE>(makeShared<COrgKdeKwinServerDecoration>(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surf))).get();
m_decos.emplace_back(makeUnique<CServerDecorationKDE>(makeShared<COrgKdeKwinServerDecoration>(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surf))).get();
if UNLIKELY (!RESOURCE->good()) {
pMgr->noMemory();
m_vDecos.pop_back();
m_decos.pop_back();
return;
}
}

View File

@@ -14,7 +14,7 @@ class CServerDecorationKDE {
bool good();
private:
SP<COrgKdeKwinServerDecoration> resource;
SP<COrgKdeKwinServerDecoration> m_resource;
};
class CServerDecorationKDEProtocol : public IWaylandProtocol {
@@ -30,8 +30,8 @@ class CServerDecorationKDEProtocol : public IWaylandProtocol {
void createDecoration(COrgKdeKwinServerDecorationManager* pMgr, uint32_t id, wl_resource* surf);
//
std::vector<UP<COrgKdeKwinServerDecorationManager>> m_vManagers;
std::vector<UP<CServerDecorationKDE>> m_vDecos;
std::vector<UP<COrgKdeKwinServerDecorationManager>> m_managers;
std::vector<UP<CServerDecorationKDE>> m_decos;
friend class CServerDecorationKDE;
};

View File

@@ -8,99 +8,99 @@
#include "../helpers/Monitor.hpp"
CSessionLockSurface::CSessionLockSurface(SP<CExtSessionLockSurfaceV1> resource_, SP<CWLSurfaceResource> surface_, PHLMONITOR pMonitor_, WP<CSessionLock> owner_) :
resource(resource_), sessionLock(owner_), pSurface(surface_), pMonitor(pMonitor_) {
if UNLIKELY (!resource->resource())
m_resource(resource_), m_sessionLock(owner_), m_surface(surface_), m_monitor(pMonitor_) {
if UNLIKELY (!m_resource->resource())
return;
resource->setDestroy([this](CExtSessionLockSurfaceV1* r) {
events.destroy.emit();
m_resource->setDestroy([this](CExtSessionLockSurfaceV1* r) {
m_events.destroy.emit();
PROTO::sessionLock->destroyResource(this);
});
resource->setOnDestroy([this](CExtSessionLockSurfaceV1* r) {
events.destroy.emit();
m_resource->setOnDestroy([this](CExtSessionLockSurfaceV1* r) {
m_events.destroy.emit();
PROTO::sessionLock->destroyResource(this);
});
resource->setAckConfigure([this](CExtSessionLockSurfaceV1* r, uint32_t serial) { ackdConfigure = true; });
m_resource->setAckConfigure([this](CExtSessionLockSurfaceV1* r, uint32_t serial) { m_ackdConfigure = true; });
listeners.surfaceCommit = pSurface->m_events.commit.registerListener([this](std::any d) {
if (!pSurface->m_current.texture) {
m_listeners.surfaceCommit = m_surface->m_events.commit.registerListener([this](std::any d) {
if (!m_surface->m_current.texture) {
LOGM(ERR, "SessionLock attached a null buffer");
resource->error(EXT_SESSION_LOCK_SURFACE_V1_ERROR_NULL_BUFFER, "Null buffer attached");
m_resource->error(EXT_SESSION_LOCK_SURFACE_V1_ERROR_NULL_BUFFER, "Null buffer attached");
return;
}
if (!ackdConfigure) {
if (!m_ackdConfigure) {
LOGM(ERR, "SessionLock committed without an ack");
resource->error(EXT_SESSION_LOCK_SURFACE_V1_ERROR_COMMIT_BEFORE_FIRST_ACK, "Committed surface before first ack");
m_resource->error(EXT_SESSION_LOCK_SURFACE_V1_ERROR_COMMIT_BEFORE_FIRST_ACK, "Committed surface before first ack");
return;
}
if (committed)
events.commit.emit();
if (m_committed)
m_events.commit.emit();
else {
pSurface->map();
events.map.emit();
m_surface->map();
m_events.map.emit();
}
committed = true;
m_committed = true;
});
listeners.surfaceDestroy = pSurface->m_events.destroy.registerListener([this](std::any d) {
m_listeners.surfaceDestroy = m_surface->m_events.destroy.registerListener([this](std::any d) {
LOGM(WARN, "SessionLockSurface object remains but surface is being destroyed???");
pSurface->unmap();
listeners.surfaceCommit.reset();
listeners.surfaceDestroy.reset();
if (g_pCompositor->m_lastFocus == pSurface)
m_surface->unmap();
m_listeners.surfaceCommit.reset();
m_listeners.surfaceDestroy.reset();
if (g_pCompositor->m_lastFocus == m_surface)
g_pCompositor->m_lastFocus.reset();
pSurface.reset();
m_surface.reset();
});
PROTO::fractional->sendScale(surface_, pMonitor_->m_scale);
sendConfigure();
listeners.monitorMode = pMonitor->m_events.modeChanged.registerListener([this](std::any data) { sendConfigure(); });
m_listeners.monitorMode = m_monitor->m_events.modeChanged.registerListener([this](std::any data) { sendConfigure(); });
}
CSessionLockSurface::~CSessionLockSurface() {
if (pSurface && pSurface->m_mapped)
pSurface->unmap();
listeners.surfaceCommit.reset();
listeners.surfaceDestroy.reset();
events.destroy.emit(); // just in case.
if (m_surface && m_surface->m_mapped)
m_surface->unmap();
m_listeners.surfaceCommit.reset();
m_listeners.surfaceDestroy.reset();
m_events.destroy.emit(); // just in case.
}
void CSessionLockSurface::sendConfigure() {
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(resource->client()));
resource->sendConfigure(SERIAL, pMonitor->m_size.x, pMonitor->m_size.y);
const auto SERIAL = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(m_resource->client()));
m_resource->sendConfigure(SERIAL, m_monitor->m_size.x, m_monitor->m_size.y);
}
bool CSessionLockSurface::good() {
return resource->resource();
return m_resource->resource();
}
bool CSessionLockSurface::inert() {
return sessionLock.expired();
return m_sessionLock.expired();
}
PHLMONITOR CSessionLockSurface::monitor() {
return pMonitor.lock();
return m_monitor.lock();
}
SP<CWLSurfaceResource> CSessionLockSurface::surface() {
return pSurface.lock();
return m_surface.lock();
}
CSessionLock::CSessionLock(SP<CExtSessionLockV1> resource_) : resource(resource_) {
if UNLIKELY (!resource->resource())
CSessionLock::CSessionLock(SP<CExtSessionLockV1> resource_) : m_resource(resource_) {
if UNLIKELY (!m_resource->resource())
return;
resource->setDestroy([this](CExtSessionLockV1* r) { PROTO::sessionLock->destroyResource(this); });
resource->setOnDestroy([this](CExtSessionLockV1* r) { PROTO::sessionLock->destroyResource(this); });
m_resource->setDestroy([this](CExtSessionLockV1* r) { PROTO::sessionLock->destroyResource(this); });
m_resource->setOnDestroy([this](CExtSessionLockV1* r) { PROTO::sessionLock->destroyResource(this); });
resource->setGetLockSurface([this](CExtSessionLockV1* r, uint32_t id, wl_resource* surf, wl_resource* output) {
if (inert) {
m_resource->setGetLockSurface([this](CExtSessionLockV1* r, uint32_t id, wl_resource* surf, wl_resource* output) {
if (m_inert) {
LOGM(ERR, "Lock is trying to send getLockSurface after it's inert");
return;
}
@@ -108,39 +108,39 @@ CSessionLock::CSessionLock(SP<CExtSessionLockV1> resource_) : resource(resource_
PROTO::sessionLock->onGetLockSurface(r, id, surf, output);
});
resource->setUnlockAndDestroy([this](CExtSessionLockV1* r) {
if (inert) {
m_resource->setUnlockAndDestroy([this](CExtSessionLockV1* r) {
if (m_inert) {
PROTO::sessionLock->destroyResource(this);
return;
}
PROTO::sessionLock->locked = false;
PROTO::sessionLock->m_locked = false;
PROTO::lockNotify->onUnlocked();
events.unlockAndDestroy.emit();
m_events.unlockAndDestroy.emit();
inert = true;
m_inert = true;
PROTO::sessionLock->destroyResource(this);
});
}
CSessionLock::~CSessionLock() {
events.destroyed.emit();
m_events.destroyed.emit();
}
void CSessionLock::sendLocked() {
resource->sendLocked();
m_resource->sendLocked();
PROTO::lockNotify->onLocked();
}
bool CSessionLock::good() {
return resource->resource();
return m_resource->resource();
}
void CSessionLock::sendDenied() {
inert = true;
resource->sendFinished();
m_inert = true;
m_resource->sendFinished();
}
CSessionLockProtocol::CSessionLockProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -148,7 +148,7 @@ CSessionLockProtocol::CSessionLockProtocol(const wl_interface* iface, const int&
}
void CSessionLockProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeUnique<CExtSessionLockManagerV1>(client, ver, id)).get();
const auto RESOURCE = m_managers.emplace_back(makeUnique<CExtSessionLockManagerV1>(client, ver, id)).get();
RESOURCE->setOnDestroy([this](CExtSessionLockManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setDestroy([this](CExtSessionLockManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
@@ -156,15 +156,15 @@ void CSessionLockProtocol::bindManager(wl_client* client, void* data, uint32_t v
}
void CSessionLockProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
std::erase_if(m_managers, [&](const auto& other) { return other->resource() == res; });
}
void CSessionLockProtocol::destroyResource(CSessionLock* lock) {
std::erase_if(m_vLocks, [&](const auto& other) { return other.get() == lock; });
std::erase_if(m_locks, [&](const auto& other) { return other.get() == lock; });
}
void CSessionLockProtocol::destroyResource(CSessionLockSurface* surf) {
std::erase_if(m_vLockSurfaces, [&](const auto& other) { return other.get() == surf; });
std::erase_if(m_lockSurfaces, [&](const auto& other) { return other.get() == surf; });
}
void CSessionLockProtocol::onLock(CExtSessionLockManagerV1* pMgr, uint32_t id) {
@@ -172,17 +172,17 @@ void CSessionLockProtocol::onLock(CExtSessionLockManagerV1* pMgr, uint32_t id) {
LOGM(LOG, "New sessionLock with id {}", id);
const auto CLIENT = pMgr->client();
const auto RESOURCE = m_vLocks.emplace_back(makeShared<CSessionLock>(makeShared<CExtSessionLockV1>(CLIENT, pMgr->version(), id)));
const auto RESOURCE = m_locks.emplace_back(makeShared<CSessionLock>(makeShared<CExtSessionLockV1>(CLIENT, pMgr->version(), id)));
if UNLIKELY (!RESOURCE->good()) {
pMgr->noMemory();
m_vLocks.pop_back();
m_locks.pop_back();
return;
}
events.newLock.emit(RESOURCE);
m_events.newLock.emit(RESOURCE);
locked = true;
m_locked = true;
}
void CSessionLockProtocol::onGetLockSurface(CExtSessionLockV1* lock, uint32_t id, wl_resource* surface, wl_resource* output) {
@@ -192,25 +192,25 @@ void CSessionLockProtocol::onGetLockSurface(CExtSessionLockV1* lock, uint32_t id
auto PMONITOR = CWLOutputResource::fromResource(output)->m_monitor.lock();
SP<CSessionLock> sessionLock;
for (auto const& l : m_vLocks) {
if (l->resource.get() == lock) {
for (auto const& l : m_locks) {
if (l->m_resource.get() == lock) {
sessionLock = l;
break;
}
}
const auto RESOURCE =
m_vLockSurfaces.emplace_back(makeShared<CSessionLockSurface>(makeShared<CExtSessionLockSurfaceV1>(lock->client(), lock->version(), id), PSURFACE, PMONITOR, sessionLock));
m_lockSurfaces.emplace_back(makeShared<CSessionLockSurface>(makeShared<CExtSessionLockSurfaceV1>(lock->client(), lock->version(), id), PSURFACE, PMONITOR, sessionLock));
if UNLIKELY (!RESOURCE->good()) {
lock->noMemory();
m_vLockSurfaces.pop_back();
m_lockSurfaces.pop_back();
return;
}
sessionLock->events.newLockSurface.emit(RESOURCE);
sessionLock->m_events.newLockSurface.emit(RESOURCE);
}
bool CSessionLockProtocol::isLocked() {
return locked;
return m_locked;
}

View File

@@ -24,16 +24,16 @@ class CSessionLockSurface {
CSignal map;
CSignal destroy;
CSignal commit;
} events;
} m_events;
private:
SP<CExtSessionLockSurfaceV1> resource;
WP<CSessionLock> sessionLock;
WP<CWLSurfaceResource> pSurface;
PHLMONITORREF pMonitor;
SP<CExtSessionLockSurfaceV1> m_resource;
WP<CSessionLock> m_sessionLock;
WP<CWLSurfaceResource> m_surface;
PHLMONITORREF m_monitor;
bool ackdConfigure = false;
bool committed = false;
bool m_ackdConfigure = false;
bool m_committed = false;
void sendConfigure();
@@ -41,7 +41,7 @@ class CSessionLockSurface {
CHyprSignalListener monitorMode;
CHyprSignalListener surfaceCommit;
CHyprSignalListener surfaceDestroy;
} listeners;
} m_listeners;
};
class CSessionLock {
@@ -57,12 +57,12 @@ class CSessionLock {
CSignal newLockSurface; // SP<CSessionLockSurface>
CSignal unlockAndDestroy;
CSignal destroyed; // fires regardless of whether there was a unlockAndDestroy or not.
} events;
} m_events;
private:
SP<CExtSessionLockV1> resource;
SP<CExtSessionLockV1> m_resource;
bool inert = false;
bool m_inert = false;
friend class CSessionLockProtocol;
};
@@ -77,7 +77,7 @@ class CSessionLockProtocol : public IWaylandProtocol {
struct {
CSignal newLock; // SP<CSessionLock>
} events;
} m_events;
private:
void onManagerResourceDestroy(wl_resource* res);
@@ -86,12 +86,12 @@ class CSessionLockProtocol : public IWaylandProtocol {
void onLock(CExtSessionLockManagerV1* pMgr, uint32_t id);
void onGetLockSurface(CExtSessionLockV1* lock, uint32_t id, wl_resource* surface, wl_resource* output);
bool locked = false;
bool m_locked = false;
//
std::vector<UP<CExtSessionLockManagerV1>> m_vManagers;
std::vector<SP<CSessionLock>> m_vLocks;
std::vector<SP<CSessionLockSurface>> m_vLockSurfaces;
std::vector<UP<CExtSessionLockManagerV1>> m_managers;
std::vector<SP<CSessionLock>> m_locks;
std::vector<SP<CSessionLockSurface>> m_lockSurfaces;
friend class CSessionLock;
friend class CSessionLockSurface;

View File

@@ -3,24 +3,24 @@
#include "../Compositor.hpp"
#include "core/Compositor.hpp"
CKeyboardShortcutsInhibitor::CKeyboardShortcutsInhibitor(SP<CZwpKeyboardShortcutsInhibitorV1> resource_, SP<CWLSurfaceResource> surf) : resource(resource_), pSurface(surf) {
if UNLIKELY (!resource->resource())
CKeyboardShortcutsInhibitor::CKeyboardShortcutsInhibitor(SP<CZwpKeyboardShortcutsInhibitorV1> resource_, SP<CWLSurfaceResource> surf) : m_resource(resource_), m_surface(surf) {
if UNLIKELY (!m_resource->resource())
return;
resource->setDestroy([this](CZwpKeyboardShortcutsInhibitorV1* pMgr) { PROTO::shortcutsInhibit->destroyInhibitor(this); });
resource->setOnDestroy([this](CZwpKeyboardShortcutsInhibitorV1* pMgr) { PROTO::shortcutsInhibit->destroyInhibitor(this); });
m_resource->setDestroy([this](CZwpKeyboardShortcutsInhibitorV1* pMgr) { PROTO::shortcutsInhibit->destroyInhibitor(this); });
m_resource->setOnDestroy([this](CZwpKeyboardShortcutsInhibitorV1* pMgr) { PROTO::shortcutsInhibit->destroyInhibitor(this); });
// I don't really care about following the spec here that much,
// let's make the app believe it's always active
resource->sendActive();
m_resource->sendActive();
}
SP<CWLSurfaceResource> CKeyboardShortcutsInhibitor::surface() {
return pSurface.lock();
return m_surface.lock();
}
bool CKeyboardShortcutsInhibitor::good() {
return resource->resource();
return m_resource->resource();
}
CKeyboardShortcutsInhibitProtocol::CKeyboardShortcutsInhibitProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -28,7 +28,7 @@ CKeyboardShortcutsInhibitProtocol::CKeyboardShortcutsInhibitProtocol(const wl_in
}
void CKeyboardShortcutsInhibitProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeUnique<CZwpKeyboardShortcutsInhibitManagerV1>(client, ver, id)).get();
const auto RESOURCE = m_managers.emplace_back(makeUnique<CZwpKeyboardShortcutsInhibitManagerV1>(client, ver, id)).get();
RESOURCE->setOnDestroy([this](CZwpKeyboardShortcutsInhibitManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setDestroy([this](CZwpKeyboardShortcutsInhibitManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
@@ -37,18 +37,18 @@ void CKeyboardShortcutsInhibitProtocol::bindManager(wl_client* client, void* dat
}
void CKeyboardShortcutsInhibitProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
std::erase_if(m_managers, [&](const auto& other) { return other->resource() == res; });
}
void CKeyboardShortcutsInhibitProtocol::destroyInhibitor(CKeyboardShortcutsInhibitor* inhibitor) {
std::erase_if(m_vInhibitors, [&](const auto& other) { return other.get() == inhibitor; });
std::erase_if(m_inhibitors, [&](const auto& other) { return other.get() == inhibitor; });
}
void CKeyboardShortcutsInhibitProtocol::onInhibit(CZwpKeyboardShortcutsInhibitManagerV1* pMgr, uint32_t id, wl_resource* surface, wl_resource* seat) {
SP<CWLSurfaceResource> surf = CWLSurfaceResource::fromResource(surface);
const auto CLIENT = pMgr->client();
for (auto const& in : m_vInhibitors) {
for (auto const& in : m_inhibitors) {
if LIKELY (in->surface() != surf)
continue;
@@ -56,12 +56,11 @@ void CKeyboardShortcutsInhibitProtocol::onInhibit(CZwpKeyboardShortcutsInhibitMa
return;
}
const auto RESOURCE =
m_vInhibitors.emplace_back(makeUnique<CKeyboardShortcutsInhibitor>(makeShared<CZwpKeyboardShortcutsInhibitorV1>(CLIENT, pMgr->version(), id), surf)).get();
const auto RESOURCE = m_inhibitors.emplace_back(makeUnique<CKeyboardShortcutsInhibitor>(makeShared<CZwpKeyboardShortcutsInhibitorV1>(CLIENT, pMgr->version(), id), surf)).get();
if UNLIKELY (!RESOURCE->good()) {
pMgr->noMemory();
m_vInhibitors.pop_back();
m_inhibitors.pop_back();
LOGM(ERR, "Failed to create an inhibitor resource");
return;
}
@@ -74,7 +73,7 @@ bool CKeyboardShortcutsInhibitProtocol::isInhibited() {
if (const auto PWINDOW = g_pCompositor->getWindowFromSurface(g_pCompositor->m_lastFocus.lock()); PWINDOW && PWINDOW->m_windowData.noShortcutsInhibit.valueOrDefault())
return false;
for (auto const& in : m_vInhibitors) {
for (auto const& in : m_inhibitors) {
if (in->surface() != g_pCompositor->m_lastFocus)
continue;

View File

@@ -16,8 +16,8 @@ class CKeyboardShortcutsInhibitor {
bool good();
private:
SP<CZwpKeyboardShortcutsInhibitorV1> resource;
WP<CWLSurfaceResource> pSurface;
SP<CZwpKeyboardShortcutsInhibitorV1> m_resource;
WP<CWLSurfaceResource> m_surface;
};
class CKeyboardShortcutsInhibitProtocol : public IWaylandProtocol {
@@ -34,8 +34,8 @@ class CKeyboardShortcutsInhibitProtocol : public IWaylandProtocol {
void onInhibit(CZwpKeyboardShortcutsInhibitManagerV1* pMgr, uint32_t id, wl_resource* surface, wl_resource* seat);
//
std::vector<UP<CZwpKeyboardShortcutsInhibitManagerV1>> m_vManagers;
std::vector<UP<CKeyboardShortcutsInhibitor>> m_vInhibitors;
std::vector<UP<CZwpKeyboardShortcutsInhibitManagerV1>> m_managers;
std::vector<UP<CKeyboardShortcutsInhibitor>> m_inhibitors;
friend class CKeyboardShortcutsInhibitor;
};

View File

@@ -6,21 +6,21 @@
CSinglePixelBuffer::CSinglePixelBuffer(uint32_t id, wl_client* client, CHyprColor col_) {
LOGM(LOG, "New single-pixel buffer with color 0x{:x}", col_.getAsHex());
color = col_.getAsHex();
m_color = col_.getAsHex();
g_pHyprRenderer->makeEGLCurrent();
m_opaque = col_.a >= 1.F;
m_texture = makeShared<CTexture>(DRM_FORMAT_ARGB8888, (uint8_t*)&color, 4, Vector2D{1, 1});
m_texture = makeShared<CTexture>(DRM_FORMAT_ARGB8888, (uint8_t*)&m_color, 4, Vector2D{1, 1});
m_resource = CWLBufferResource::create(makeShared<CWlBuffer>(client, 1, id));
success = m_texture->m_iTexID;
m_success = m_texture->m_iTexID;
size = {1, 1};
if (!success)
if (!m_success)
Debug::log(ERR, "Failed creating a single pixel texture: null texture id");
}
@@ -50,7 +50,7 @@ Aquamarine::SDMABUFAttrs CSinglePixelBuffer::dmabuf() {
}
std::tuple<uint8_t*, uint32_t, size_t> CSinglePixelBuffer::beginDataPtr(uint32_t flags) {
return {(uint8_t*)&color, DRM_FORMAT_ARGB8888, 4};
return {(uint8_t*)&m_color, DRM_FORMAT_ARGB8888, 4};
}
void CSinglePixelBuffer::endDataPtr() {
@@ -62,45 +62,45 @@ bool CSinglePixelBuffer::good() {
}
CSinglePixelBufferResource::CSinglePixelBufferResource(uint32_t id, wl_client* client, CHyprColor color) {
buffer = makeShared<CSinglePixelBuffer>(id, client, color);
m_buffer = makeShared<CSinglePixelBuffer>(id, client, color);
if UNLIKELY (!buffer->good())
if UNLIKELY (!m_buffer->good())
return;
buffer->m_resource->m_buffer = buffer;
m_buffer->m_resource->m_buffer = m_buffer;
listeners.bufferResourceDestroy = buffer->events.destroy.registerListener([this](std::any d) {
listeners.bufferResourceDestroy.reset();
m_listeners.bufferResourceDestroy = m_buffer->events.destroy.registerListener([this](std::any d) {
m_listeners.bufferResourceDestroy.reset();
PROTO::singlePixel->destroyResource(this);
});
}
bool CSinglePixelBufferResource::good() {
return buffer->good();
return m_buffer->good();
}
CSinglePixelBufferManagerResource::CSinglePixelBufferManagerResource(SP<CWpSinglePixelBufferManagerV1> resource_) : resource(resource_) {
CSinglePixelBufferManagerResource::CSinglePixelBufferManagerResource(SP<CWpSinglePixelBufferManagerV1> resource_) : m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setDestroy([this](CWpSinglePixelBufferManagerV1* r) { PROTO::singlePixel->destroyResource(this); });
resource->setOnDestroy([this](CWpSinglePixelBufferManagerV1* r) { PROTO::singlePixel->destroyResource(this); });
m_resource->setDestroy([this](CWpSinglePixelBufferManagerV1* r) { PROTO::singlePixel->destroyResource(this); });
m_resource->setOnDestroy([this](CWpSinglePixelBufferManagerV1* r) { PROTO::singlePixel->destroyResource(this); });
resource->setCreateU32RgbaBuffer([this](CWpSinglePixelBufferManagerV1* res, uint32_t id, uint32_t r, uint32_t g, uint32_t b, uint32_t a) {
m_resource->setCreateU32RgbaBuffer([this](CWpSinglePixelBufferManagerV1* res, uint32_t id, uint32_t r, uint32_t g, uint32_t b, uint32_t a) {
CHyprColor color{r / (float)std::numeric_limits<uint32_t>::max(), g / (float)std::numeric_limits<uint32_t>::max(), b / (float)std::numeric_limits<uint32_t>::max(),
a / (float)std::numeric_limits<uint32_t>::max()};
const auto RESOURCE = PROTO::singlePixel->m_vBuffers.emplace_back(makeShared<CSinglePixelBufferResource>(id, resource->client(), color));
const auto RESOURCE = PROTO::singlePixel->m_buffers.emplace_back(makeShared<CSinglePixelBufferResource>(id, m_resource->client(), color));
if UNLIKELY (!RESOURCE->good()) {
res->noMemory();
PROTO::singlePixel->m_vBuffers.pop_back();
PROTO::singlePixel->m_buffers.pop_back();
return;
}
});
}
bool CSinglePixelBufferManagerResource::good() {
return resource->resource();
return m_resource->resource();
}
CSinglePixelProtocol::CSinglePixelProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -108,19 +108,19 @@ CSinglePixelProtocol::CSinglePixelProtocol(const wl_interface* iface, const int&
}
void CSinglePixelProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeShared<CSinglePixelBufferManagerResource>(makeShared<CWpSinglePixelBufferManagerV1>(client, ver, id)));
const auto RESOURCE = m_managers.emplace_back(makeShared<CSinglePixelBufferManagerResource>(makeShared<CWpSinglePixelBufferManagerV1>(client, ver, id)));
if UNLIKELY (!RESOURCE->good()) {
wl_client_post_no_memory(client);
m_vManagers.pop_back();
m_managers.pop_back();
return;
}
}
void CSinglePixelProtocol::destroyResource(CSinglePixelBufferManagerResource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == res; });
std::erase_if(m_managers, [&](const auto& other) { return other.get() == res; });
}
void CSinglePixelProtocol::destroyResource(CSinglePixelBufferResource* surf) {
std::erase_if(m_vBuffers, [&](const auto& other) { return other.get() == surf; });
std::erase_if(m_buffers, [&](const auto& other) { return other.get() == surf; });
}

View File

@@ -20,14 +20,10 @@ class CSinglePixelBuffer : public IHLBuffer {
virtual void endDataPtr();
//
bool good();
bool success = false;
bool m_success = false;
private:
uint32_t color = 0x00000000;
struct {
CHyprSignalListener resourceDestroy;
} listeners;
uint32_t m_color = 0x00000000;
};
class CSinglePixelBufferResource {
@@ -38,11 +34,11 @@ class CSinglePixelBufferResource {
bool good();
private:
SP<CSinglePixelBuffer> buffer;
SP<CSinglePixelBuffer> m_buffer;
struct {
CHyprSignalListener bufferResourceDestroy;
} listeners;
} m_listeners;
};
class CSinglePixelBufferManagerResource {
@@ -52,7 +48,7 @@ class CSinglePixelBufferManagerResource {
bool good();
private:
SP<CWpSinglePixelBufferManagerV1> resource;
SP<CWpSinglePixelBufferManagerV1> m_resource;
};
class CSinglePixelProtocol : public IWaylandProtocol {
@@ -66,8 +62,8 @@ class CSinglePixelProtocol : public IWaylandProtocol {
void destroyResource(CSinglePixelBufferResource* resource);
//
std::vector<SP<CSinglePixelBufferManagerResource>> m_vManagers;
std::vector<SP<CSinglePixelBufferResource>> m_vBuffers;
std::vector<SP<CSinglePixelBufferManagerResource>> m_managers;
std::vector<SP<CSinglePixelBufferResource>> m_buffers;
friend class CSinglePixelBufferManagerResource;
friend class CSinglePixelBufferResource;

View File

@@ -9,154 +9,154 @@
#include <algorithm>
#include <cstring>
CTabletPadStripV2Resource::CTabletPadStripV2Resource(SP<CZwpTabletPadStripV2> resource_, uint32_t id_) : id(id_), resource(resource_) {
CTabletPadStripV2Resource::CTabletPadStripV2Resource(SP<CZwpTabletPadStripV2> resource_, uint32_t id_) : m_id(id_), m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setDestroy([this](CZwpTabletPadStripV2* r) { PROTO::tablet->destroyResource(this); });
resource->setOnDestroy([this](CZwpTabletPadStripV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setDestroy([this](CZwpTabletPadStripV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setOnDestroy([this](CZwpTabletPadStripV2* r) { PROTO::tablet->destroyResource(this); });
}
bool CTabletPadStripV2Resource::good() {
return resource->resource();
return m_resource->resource();
}
CTabletPadRingV2Resource::CTabletPadRingV2Resource(SP<CZwpTabletPadRingV2> resource_, uint32_t id_) : id(id_), resource(resource_) {
CTabletPadRingV2Resource::CTabletPadRingV2Resource(SP<CZwpTabletPadRingV2> resource_, uint32_t id_) : m_id(id_), m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setDestroy([this](CZwpTabletPadRingV2* r) { PROTO::tablet->destroyResource(this); });
resource->setOnDestroy([this](CZwpTabletPadRingV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setDestroy([this](CZwpTabletPadRingV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setOnDestroy([this](CZwpTabletPadRingV2* r) { PROTO::tablet->destroyResource(this); });
}
bool CTabletPadRingV2Resource::good() {
return resource->resource();
return m_resource->resource();
}
CTabletPadGroupV2Resource::CTabletPadGroupV2Resource(SP<CZwpTabletPadGroupV2> resource_, size_t idx_) : idx(idx_), resource(resource_) {
CTabletPadGroupV2Resource::CTabletPadGroupV2Resource(SP<CZwpTabletPadGroupV2> resource_, size_t idx_) : m_idx(idx_), m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setDestroy([this](CZwpTabletPadGroupV2* r) { PROTO::tablet->destroyResource(this); });
resource->setOnDestroy([this](CZwpTabletPadGroupV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setDestroy([this](CZwpTabletPadGroupV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setOnDestroy([this](CZwpTabletPadGroupV2* r) { PROTO::tablet->destroyResource(this); });
}
bool CTabletPadGroupV2Resource::good() {
return resource->resource();
return m_resource->resource();
}
void CTabletPadGroupV2Resource::sendData(SP<CTabletPad> pad, SP<Aquamarine::ITabletPad::STabletPadGroup> group) {
resource->sendModes(group->modes);
m_resource->sendModes(group->modes);
wl_array buttonArr;
wl_array_init(&buttonArr);
wl_array_add(&buttonArr, group->buttons.size() * sizeof(int));
memcpy(buttonArr.data, group->buttons.data(), group->buttons.size() * sizeof(int));
resource->sendButtons(&buttonArr);
m_resource->sendButtons(&buttonArr);
wl_array_release(&buttonArr);
for (size_t i = 0; i < group->strips.size(); ++i) {
const auto RESOURCE =
PROTO::tablet->m_vStrips.emplace_back(makeShared<CTabletPadStripV2Resource>(makeShared<CZwpTabletPadStripV2>(resource->client(), resource->version(), 0), i));
PROTO::tablet->m_strips.emplace_back(makeShared<CTabletPadStripV2Resource>(makeShared<CZwpTabletPadStripV2>(m_resource->client(), m_resource->version(), 0), i));
if UNLIKELY (!RESOURCE->good()) {
resource->noMemory();
PROTO::tablet->m_vStrips.pop_back();
m_resource->noMemory();
PROTO::tablet->m_strips.pop_back();
return;
}
resource->sendStrip(RESOURCE->resource.get());
m_resource->sendStrip(RESOURCE->m_resource.get());
}
for (size_t i = 0; i < group->rings.size(); ++i) {
const auto RESOURCE =
PROTO::tablet->m_vRings.emplace_back(makeShared<CTabletPadRingV2Resource>(makeShared<CZwpTabletPadRingV2>(resource->client(), resource->version(), 0), i));
PROTO::tablet->m_rings.emplace_back(makeShared<CTabletPadRingV2Resource>(makeShared<CZwpTabletPadRingV2>(m_resource->client(), m_resource->version(), 0), i));
if UNLIKELY (!RESOURCE->good()) {
resource->noMemory();
PROTO::tablet->m_vRings.pop_back();
m_resource->noMemory();
PROTO::tablet->m_rings.pop_back();
return;
}
resource->sendRing(RESOURCE->resource.get());
m_resource->sendRing(RESOURCE->m_resource.get());
}
resource->sendDone();
m_resource->sendDone();
}
CTabletPadV2Resource::CTabletPadV2Resource(SP<CZwpTabletPadV2> resource_, SP<CTabletPad> pad_, SP<CTabletSeat> seat_) : pad(pad_), seat(seat_), resource(resource_) {
CTabletPadV2Resource::CTabletPadV2Resource(SP<CZwpTabletPadV2> resource_, SP<CTabletPad> pad_, SP<CTabletSeat> seat_) : m_pad(pad_), m_seat(seat_), m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setDestroy([this](CZwpTabletPadV2* r) { PROTO::tablet->destroyResource(this); });
resource->setOnDestroy([this](CZwpTabletPadV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setDestroy([this](CZwpTabletPadV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setOnDestroy([this](CZwpTabletPadV2* r) { PROTO::tablet->destroyResource(this); });
}
bool CTabletPadV2Resource::good() {
return resource->resource();
return m_resource->resource();
}
void CTabletPadV2Resource::sendData() {
// this is dodgy as fuck. I hate wl_array. it's expanded wl_array_for_each because C++ would complain about the implicit casts
for (auto const& p : pad->aq()->paths) {
resource->sendPath(p.c_str());
for (auto const& p : m_pad->aq()->paths) {
m_resource->sendPath(p.c_str());
}
resource->sendButtons(pad->aq()->buttons);
m_resource->sendButtons(m_pad->aq()->buttons);
for (size_t i = 0; i < pad->aq()->groups.size(); ++i) {
createGroup(pad->aq()->groups.at(i), i);
for (size_t i = 0; i < m_pad->aq()->groups.size(); ++i) {
createGroup(m_pad->aq()->groups.at(i), i);
}
resource->sendDone();
m_resource->sendDone();
}
void CTabletPadV2Resource::createGroup(SP<Aquamarine::ITabletPad::STabletPadGroup> group, size_t idx) {
const auto RESOURCE =
PROTO::tablet->m_vGroups.emplace_back(makeShared<CTabletPadGroupV2Resource>(makeShared<CZwpTabletPadGroupV2>(resource->client(), resource->version(), 0), idx));
PROTO::tablet->m_groups.emplace_back(makeShared<CTabletPadGroupV2Resource>(makeShared<CZwpTabletPadGroupV2>(m_resource->client(), m_resource->version(), 0), idx));
if UNLIKELY (!RESOURCE->good()) {
resource->noMemory();
PROTO::tablet->m_vGroups.pop_back();
m_resource->noMemory();
PROTO::tablet->m_groups.pop_back();
return;
}
resource->sendGroup(RESOURCE->resource.get());
m_resource->sendGroup(RESOURCE->m_resource.get());
RESOURCE->sendData(pad.lock(), group);
RESOURCE->sendData(m_pad.lock(), group);
}
CTabletV2Resource::CTabletV2Resource(SP<CZwpTabletV2> resource_, SP<CTablet> tablet_, SP<CTabletSeat> seat_) : tablet(tablet_), seat(seat_), resource(resource_) {
CTabletV2Resource::CTabletV2Resource(SP<CZwpTabletV2> resource_, SP<CTablet> tablet_, SP<CTabletSeat> seat_) : m_tablet(tablet_), m_seat(seat_), m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setDestroy([this](CZwpTabletV2* r) { PROTO::tablet->destroyResource(this); });
resource->setOnDestroy([this](CZwpTabletV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setDestroy([this](CZwpTabletV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setOnDestroy([this](CZwpTabletV2* r) { PROTO::tablet->destroyResource(this); });
}
bool CTabletV2Resource::good() {
return resource->resource();
return m_resource->resource();
}
void CTabletV2Resource::sendData() {
resource->sendName(tablet->m_deviceName.c_str());
resource->sendId(tablet->aq()->usbVendorID, tablet->aq()->usbProductID);
m_resource->sendName(m_tablet->m_deviceName.c_str());
m_resource->sendId(m_tablet->aq()->usbVendorID, m_tablet->aq()->usbProductID);
for (auto const& p : tablet->aq()->paths) {
resource->sendPath(p.c_str());
for (auto const& p : m_tablet->aq()->paths) {
m_resource->sendPath(p.c_str());
}
resource->sendDone();
m_resource->sendDone();
}
CTabletToolV2Resource::CTabletToolV2Resource(SP<CZwpTabletToolV2> resource_, SP<CTabletTool> tool_, SP<CTabletSeat> seat_) : tool(tool_), seat(seat_), resource(resource_) {
CTabletToolV2Resource::CTabletToolV2Resource(SP<CZwpTabletToolV2> resource_, SP<CTabletTool> tool_, SP<CTabletSeat> seat_) : m_tool(tool_), m_seat(seat_), m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setDestroy([this](CZwpTabletToolV2* r) { PROTO::tablet->destroyResource(this); });
resource->setOnDestroy([this](CZwpTabletToolV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setDestroy([this](CZwpTabletToolV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setOnDestroy([this](CZwpTabletToolV2* r) { PROTO::tablet->destroyResource(this); });
resource->setSetCursor([](CZwpTabletToolV2* r, uint32_t serial, wl_resource* surf, int32_t hot_x, int32_t hot_y) {
m_resource->setSetCursor([](CZwpTabletToolV2* r, uint32_t serial, wl_resource* surf, int32_t hot_x, int32_t hot_y) {
if (!g_pSeatManager->m_state.pointerFocusResource || g_pSeatManager->m_state.pointerFocusResource->client() != r->client())
return;
@@ -165,12 +165,12 @@ CTabletToolV2Resource::CTabletToolV2Resource(SP<CZwpTabletToolV2> resource_, SP<
}
CTabletToolV2Resource::~CTabletToolV2Resource() {
if (frameSource)
wl_event_source_remove(frameSource);
if (m_frameSource)
wl_event_source_remove(m_frameSource);
}
bool CTabletToolV2Resource::good() {
return resource->resource();
return m_resource->resource();
}
void CTabletToolV2Resource::sendData() {
@@ -188,120 +188,120 @@ void CTabletToolV2Resource::sendData() {
UNREACHABLE();
};
resource->sendType(AQ_TYPE_TO_PROTO(tool->aq()->type));
resource->sendHardwareSerial(tool->aq()->serial >> 32, tool->aq()->serial & 0xFFFFFFFF);
resource->sendHardwareIdWacom(tool->aq()->id >> 32, tool->aq()->id & 0xFFFFFFFF);
if (tool->m_toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_DISTANCE)
resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE);
if (tool->m_toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_PRESSURE)
resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE);
if (tool->m_toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_ROTATION)
resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION);
if (tool->m_toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_SLIDER)
resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER);
if (tool->m_toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_TILT)
resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_TILT);
if (tool->m_toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_WHEEL)
resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL);
resource->sendDone();
m_resource->sendType(AQ_TYPE_TO_PROTO(m_tool->aq()->type));
m_resource->sendHardwareSerial(m_tool->aq()->serial >> 32, m_tool->aq()->serial & 0xFFFFFFFF);
m_resource->sendHardwareIdWacom(m_tool->aq()->id >> 32, m_tool->aq()->id & 0xFFFFFFFF);
if (m_tool->m_toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_DISTANCE)
m_resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE);
if (m_tool->m_toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_PRESSURE)
m_resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE);
if (m_tool->m_toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_ROTATION)
m_resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION);
if (m_tool->m_toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_SLIDER)
m_resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER);
if (m_tool->m_toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_TILT)
m_resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_TILT);
if (m_tool->m_toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_WHEEL)
m_resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL);
m_resource->sendDone();
}
void CTabletToolV2Resource::queueFrame() {
if (frameSource)
if (m_frameSource)
return;
frameSource = wl_event_loop_add_idle(g_pCompositor->m_wlEventLoop, [](void* data) { ((CTabletToolV2Resource*)data)->sendFrame(false); }, this);
m_frameSource = wl_event_loop_add_idle(g_pCompositor->m_wlEventLoop, [](void* data) { ((CTabletToolV2Resource*)data)->sendFrame(false); }, this);
}
void CTabletToolV2Resource::sendFrame(bool removeSource) {
if (frameSource) {
if (m_frameSource) {
if (removeSource)
wl_event_source_remove(frameSource);
frameSource = nullptr;
wl_event_source_remove(m_frameSource);
m_frameSource = nullptr;
}
if (!current)
if (!m_current)
return;
resource->sendFrame(Time::millis(Time::steadyNow()));
m_resource->sendFrame(Time::millis(Time::steadyNow()));
}
CTabletSeat::CTabletSeat(SP<CZwpTabletSeatV2> resource_) : resource(resource_) {
CTabletSeat::CTabletSeat(SP<CZwpTabletSeatV2> resource_) : m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setDestroy([this](CZwpTabletSeatV2* r) { PROTO::tablet->destroyResource(this); });
resource->setOnDestroy([this](CZwpTabletSeatV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setDestroy([this](CZwpTabletSeatV2* r) { PROTO::tablet->destroyResource(this); });
m_resource->setOnDestroy([this](CZwpTabletSeatV2* r) { PROTO::tablet->destroyResource(this); });
}
bool CTabletSeat::good() {
return resource->resource();
return m_resource->resource();
}
void CTabletSeat::sendTool(SP<CTabletTool> tool) {
const auto RESOURCE =
PROTO::tablet->m_vTools.emplace_back(makeShared<CTabletToolV2Resource>(makeShared<CZwpTabletToolV2>(resource->client(), resource->version(), 0), tool, self.lock()));
PROTO::tablet->m_tools.emplace_back(makeShared<CTabletToolV2Resource>(makeShared<CZwpTabletToolV2>(m_resource->client(), m_resource->version(), 0), tool, m_self.lock()));
if UNLIKELY (!RESOURCE->good()) {
resource->noMemory();
PROTO::tablet->m_vTools.pop_back();
m_resource->noMemory();
PROTO::tablet->m_tools.pop_back();
return;
}
resource->sendToolAdded(RESOURCE->resource.get());
m_resource->sendToolAdded(RESOURCE->m_resource.get());
RESOURCE->sendData();
tools.emplace_back(RESOURCE);
m_tools.emplace_back(RESOURCE);
}
void CTabletSeat::sendPad(SP<CTabletPad> pad) {
const auto RESOURCE =
PROTO::tablet->m_vPads.emplace_back(makeShared<CTabletPadV2Resource>(makeShared<CZwpTabletPadV2>(resource->client(), resource->version(), 0), pad, self.lock()));
PROTO::tablet->m_pads.emplace_back(makeShared<CTabletPadV2Resource>(makeShared<CZwpTabletPadV2>(m_resource->client(), m_resource->version(), 0), pad, m_self.lock()));
if UNLIKELY (!RESOURCE->good()) {
resource->noMemory();
PROTO::tablet->m_vPads.pop_back();
m_resource->noMemory();
PROTO::tablet->m_pads.pop_back();
return;
}
resource->sendPadAdded(RESOURCE->resource.get());
m_resource->sendPadAdded(RESOURCE->m_resource.get());
RESOURCE->sendData();
pads.emplace_back(RESOURCE);
m_pads.emplace_back(RESOURCE);
}
void CTabletSeat::sendTablet(SP<CTablet> tablet) {
const auto RESOURCE =
PROTO::tablet->m_vTablets.emplace_back(makeShared<CTabletV2Resource>(makeShared<CZwpTabletV2>(resource->client(), resource->version(), 0), tablet, self.lock()));
PROTO::tablet->m_tablets.emplace_back(makeShared<CTabletV2Resource>(makeShared<CZwpTabletV2>(m_resource->client(), m_resource->version(), 0), tablet, m_self.lock()));
if UNLIKELY (!RESOURCE->good()) {
resource->noMemory();
PROTO::tablet->m_vTablets.pop_back();
m_resource->noMemory();
PROTO::tablet->m_tablets.pop_back();
return;
}
resource->sendTabletAdded(RESOURCE->resource.get());
m_resource->sendTabletAdded(RESOURCE->m_resource.get());
RESOURCE->sendData();
tablets.emplace_back(RESOURCE);
m_tablets.emplace_back(RESOURCE);
}
void CTabletSeat::sendData() {
for (auto const& tw : PROTO::tablet->tablets) {
for (auto const& tw : PROTO::tablet->m_tabletDevices) {
if (tw.expired())
continue;
sendTablet(tw.lock());
}
for (auto const& tw : PROTO::tablet->tools) {
for (auto const& tw : PROTO::tablet->m_toolDevices) {
if (tw.expired())
continue;
sendTool(tw.lock());
}
for (auto const& tw : PROTO::tablet->pads) {
for (auto const& tw : PROTO::tablet->m_padDevices) {
if (tw.expired())
continue;
@@ -314,7 +314,7 @@ CTabletV2Protocol::CTabletV2Protocol(const wl_interface* iface, const int& ver,
}
void CTabletV2Protocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeUnique<CZwpTabletManagerV2>(client, ver, id)).get();
const auto RESOURCE = m_managers.emplace_back(makeUnique<CZwpTabletManagerV2>(client, ver, id)).get();
RESOURCE->setOnDestroy([this](CZwpTabletManagerV2* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setDestroy([this](CZwpTabletManagerV2* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
@@ -322,218 +322,218 @@ void CTabletV2Protocol::bindManager(wl_client* client, void* data, uint32_t ver,
}
void CTabletV2Protocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
std::erase_if(m_managers, [&](const auto& other) { return other->resource() == res; });
}
void CTabletV2Protocol::destroyResource(CTabletSeat* resource) {
std::erase_if(m_vSeats, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_seats, [&](const auto& other) { return other.get() == resource; });
}
void CTabletV2Protocol::destroyResource(CTabletToolV2Resource* resource) {
std::erase_if(m_vTools, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_tools, [&](const auto& other) { return other.get() == resource; });
}
void CTabletV2Protocol::destroyResource(CTabletV2Resource* resource) {
std::erase_if(m_vTablets, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_tablets, [&](const auto& other) { return other.get() == resource; });
}
void CTabletV2Protocol::destroyResource(CTabletPadV2Resource* resource) {
std::erase_if(m_vPads, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_pads, [&](const auto& other) { return other.get() == resource; });
}
void CTabletV2Protocol::destroyResource(CTabletPadGroupV2Resource* resource) {
std::erase_if(m_vGroups, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_groups, [&](const auto& other) { return other.get() == resource; });
}
void CTabletV2Protocol::destroyResource(CTabletPadRingV2Resource* resource) {
std::erase_if(m_vRings, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_rings, [&](const auto& other) { return other.get() == resource; });
}
void CTabletV2Protocol::destroyResource(CTabletPadStripV2Resource* resource) {
std::erase_if(m_vStrips, [&](const auto& other) { return other.get() == resource; });
std::erase_if(m_strips, [&](const auto& other) { return other.get() == resource; });
}
void CTabletV2Protocol::onGetSeat(CZwpTabletManagerV2* pMgr, uint32_t id, wl_resource* seat) {
const auto RESOURCE = m_vSeats.emplace_back(makeShared<CTabletSeat>(makeShared<CZwpTabletSeatV2>(pMgr->client(), pMgr->version(), id)));
const auto RESOURCE = m_seats.emplace_back(makeShared<CTabletSeat>(makeShared<CZwpTabletSeatV2>(pMgr->client(), pMgr->version(), id)));
if UNLIKELY (!RESOURCE->good()) {
pMgr->noMemory();
m_vSeats.pop_back();
m_seats.pop_back();
return;
}
RESOURCE->self = RESOURCE;
RESOURCE->m_self = RESOURCE;
RESOURCE->sendData();
}
void CTabletV2Protocol::registerDevice(SP<CTablet> tablet) {
for (auto const& s : m_vSeats) {
for (auto const& s : m_seats) {
s->sendTablet(tablet);
}
tablets.emplace_back(tablet);
m_tabletDevices.emplace_back(tablet);
}
void CTabletV2Protocol::registerDevice(SP<CTabletTool> tool) {
for (auto const& s : m_vSeats) {
for (auto const& s : m_seats) {
s->sendTool(tool);
}
tools.emplace_back(tool);
m_toolDevices.emplace_back(tool);
}
void CTabletV2Protocol::registerDevice(SP<CTabletPad> pad) {
for (auto const& s : m_vSeats) {
for (auto const& s : m_seats) {
s->sendPad(pad);
}
pads.emplace_back(pad);
m_padDevices.emplace_back(pad);
}
void CTabletV2Protocol::unregisterDevice(SP<CTablet> tablet) {
for (auto const& t : m_vTablets) {
if (t->tablet == tablet) {
t->resource->sendRemoved();
t->inert = true;
for (auto const& t : m_tablets) {
if (t->m_tablet == tablet) {
t->m_resource->sendRemoved();
t->m_inert = true;
}
}
std::erase_if(tablets, [tablet](const auto& e) { return e.expired() || e == tablet; });
std::erase_if(m_tabletDevices, [tablet](const auto& e) { return e.expired() || e == tablet; });
}
void CTabletV2Protocol::unregisterDevice(SP<CTabletTool> tool) {
for (auto const& t : m_vTools) {
if (t->tool == tool) {
t->resource->sendRemoved();
t->inert = true;
for (auto const& t : m_tools) {
if (t->m_tool == tool) {
t->m_resource->sendRemoved();
t->m_inert = true;
}
}
std::erase_if(tools, [tool](const auto& e) { return e.expired() || e == tool; });
std::erase_if(m_toolDevices, [tool](const auto& e) { return e.expired() || e == tool; });
}
void CTabletV2Protocol::unregisterDevice(SP<CTabletPad> pad) {
for (auto const& t : m_vPads) {
if (t->pad == pad) {
t->resource->sendRemoved();
t->inert = true;
for (auto const& t : m_pads) {
if (t->m_pad == pad) {
t->m_resource->sendRemoved();
t->m_inert = true;
}
}
std::erase_if(pads, [pad](const auto& e) { return e.expired() || e == pad; });
std::erase_if(m_padDevices, [pad](const auto& e) { return e.expired() || e == pad; });
}
void CTabletV2Protocol::recheckRegisteredDevices() {
std::erase_if(tablets, [](const auto& e) { return e.expired(); });
std::erase_if(tools, [](const auto& e) { return e.expired(); });
std::erase_if(pads, [](const auto& e) { return e.expired(); });
std::erase_if(m_tabletDevices, [](const auto& e) { return e.expired(); });
std::erase_if(m_toolDevices, [](const auto& e) { return e.expired(); });
std::erase_if(m_padDevices, [](const auto& e) { return e.expired(); });
// now we need to send removed events
for (auto const& t : m_vTablets) {
if (!t->tablet.expired() || t->inert)
for (auto const& t : m_tablets) {
if (!t->m_tablet.expired() || t->m_inert)
continue;
t->resource->sendRemoved();
t->inert = true;
t->m_resource->sendRemoved();
t->m_inert = true;
}
for (auto const& t : m_vTools) {
if (!t->tool.expired() || t->inert)
for (auto const& t : m_tools) {
if (!t->m_tool.expired() || t->m_inert)
continue;
if (t->current) {
t->resource->sendProximityOut();
if (t->m_current) {
t->m_resource->sendProximityOut();
t->sendFrame();
t->lastSurf.reset();
t->m_lastSurf.reset();
}
t->resource->sendRemoved();
t->inert = true;
t->m_resource->sendRemoved();
t->m_inert = true;
}
for (auto const& t : m_vPads) {
if (!t->pad.expired() || t->inert)
for (auto const& t : m_pads) {
if (!t->m_pad.expired() || t->m_inert)
continue;
t->resource->sendRemoved();
t->inert = true;
t->m_resource->sendRemoved();
t->m_inert = true;
}
}
void CTabletV2Protocol::pressure(SP<CTabletTool> tool, double value) {
for (auto const& t : m_vTools) {
if (t->tool != tool || !t->current)
for (auto const& t : m_tools) {
if (t->m_tool != tool || !t->m_current)
continue;
t->resource->sendPressure(std::clamp(value * 65535, 0.0, 65535.0));
t->m_resource->sendPressure(std::clamp(value * 65535, 0.0, 65535.0));
t->queueFrame();
}
}
void CTabletV2Protocol::distance(SP<CTabletTool> tool, double value) {
for (auto const& t : m_vTools) {
if (t->tool != tool || !t->current)
for (auto const& t : m_tools) {
if (t->m_tool != tool || !t->m_current)
continue;
t->resource->sendDistance(std::clamp(value * 65535, 0.0, 65535.0));
t->m_resource->sendDistance(std::clamp(value * 65535, 0.0, 65535.0));
t->queueFrame();
}
}
void CTabletV2Protocol::rotation(SP<CTabletTool> tool, double value) {
for (auto const& t : m_vTools) {
if (t->tool != tool || !t->current)
for (auto const& t : m_tools) {
if (t->m_tool != tool || !t->m_current)
continue;
t->resource->sendRotation(wl_fixed_from_double(value));
t->m_resource->sendRotation(wl_fixed_from_double(value));
t->queueFrame();
}
}
void CTabletV2Protocol::slider(SP<CTabletTool> tool, double value) {
for (auto const& t : m_vTools) {
if (t->tool != tool || !t->current)
for (auto const& t : m_tools) {
if (t->m_tool != tool || !t->m_current)
continue;
t->resource->sendSlider(std::clamp(value * 65535, -65535.0, 65535.0));
t->m_resource->sendSlider(std::clamp(value * 65535, -65535.0, 65535.0));
t->queueFrame();
}
}
void CTabletV2Protocol::wheel(SP<CTabletTool> tool, double value) {
for (auto const& t : m_vTools) {
if (t->tool != tool || !t->current)
for (auto const& t : m_tools) {
if (t->m_tool != tool || !t->m_current)
continue;
t->resource->sendWheel(wl_fixed_from_double(value), 0);
t->m_resource->sendWheel(wl_fixed_from_double(value), 0);
t->queueFrame();
}
}
void CTabletV2Protocol::tilt(SP<CTabletTool> tool, const Vector2D& value) {
for (auto const& t : m_vTools) {
if (t->tool != tool || !t->current)
for (auto const& t : m_tools) {
if (t->m_tool != tool || !t->m_current)
continue;
t->resource->sendTilt(wl_fixed_from_double(value.x), wl_fixed_from_double(value.y));
t->m_resource->sendTilt(wl_fixed_from_double(value.x), wl_fixed_from_double(value.y));
t->queueFrame();
}
}
void CTabletV2Protocol::up(SP<CTabletTool> tool) {
for (auto const& t : m_vTools) {
if (t->tool != tool || !t->current)
for (auto const& t : m_tools) {
if (t->m_tool != tool || !t->m_current)
continue;
t->resource->sendUp();
t->m_resource->sendUp();
t->queueFrame();
}
}
void CTabletV2Protocol::down(SP<CTabletTool> tool) {
for (auto const& t : m_vTools) {
if (t->tool != tool || !t->current)
for (auto const& t : m_tools) {
if (t->m_tool != tool || !t->m_current)
continue;
auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(t->resource->client()));
t->resource->sendDown(serial);
auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(t->m_resource->client()));
t->m_resource->sendDown(serial);
t->queueFrame();
}
}
@@ -545,25 +545,25 @@ void CTabletV2Protocol::proximityIn(SP<CTabletTool> tool, SP<CTablet> tablet, SP
SP<CTabletToolV2Resource> toolResource;
SP<CTabletV2Resource> tabletResource;
for (auto const& t : m_vTools) {
if (t->tool != tool || t->resource->client() != CLIENT)
for (auto const& t : m_tools) {
if (t->m_tool != tool || t->m_resource->client() != CLIENT)
continue;
if (t->seat.expired()) {
if (t->m_seat.expired()) {
LOGM(ERR, "proximityIn on a tool without a seat parent");
return;
}
if (t->lastSurf == surf)
if (t->m_lastSurf == surf)
return;
toolResource = t;
for (auto const& tab : m_vTablets) {
if (tab->tablet != tablet)
for (auto const& tab : m_tablets) {
if (tab->m_tablet != tablet)
continue;
if (tab->seat != t->seat || !tab->seat)
if (tab->m_seat != t->m_seat || !tab->m_seat)
continue;
tabletResource = tab;
@@ -576,67 +576,67 @@ void CTabletV2Protocol::proximityIn(SP<CTabletTool> tool, SP<CTablet> tablet, SP
return;
}
toolResource->current = true;
toolResource->lastSurf = surf;
toolResource->m_current = true;
toolResource->m_lastSurf = surf;
auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(toolResource->resource->client()));
toolResource->resource->sendProximityIn(serial, tabletResource->resource.get(), surf->getResource()->resource());
auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(toolResource->m_resource->client()));
toolResource->m_resource->sendProximityIn(serial, tabletResource->m_resource.get(), surf->getResource()->resource());
toolResource->queueFrame();
LOGM(ERR, "proximityIn: found no resource to send enter");
}
void CTabletV2Protocol::proximityOut(SP<CTabletTool> tool) {
for (auto const& t : m_vTools) {
if (t->tool != tool || !t->current)
for (auto const& t : m_tools) {
if (t->m_tool != tool || !t->m_current)
continue;
t->lastSurf.reset();
t->resource->sendProximityOut();
t->m_lastSurf.reset();
t->m_resource->sendProximityOut();
t->sendFrame();
t->current = false;
t->m_current = false;
}
}
void CTabletV2Protocol::buttonTool(SP<CTabletTool> tool, uint32_t button, uint32_t state) {
for (auto const& t : m_vTools) {
if (t->tool != tool || !t->current)
for (auto const& t : m_tools) {
if (t->m_tool != tool || !t->m_current)
continue;
auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(t->resource->client()));
t->resource->sendButton(serial, button, (zwpTabletToolV2ButtonState)state);
auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(t->m_resource->client()));
t->m_resource->sendButton(serial, button, (zwpTabletToolV2ButtonState)state);
t->queueFrame();
}
}
void CTabletV2Protocol::motion(SP<CTabletTool> tool, const Vector2D& value) {
for (auto const& t : m_vTools) {
if (t->tool != tool || !t->current)
for (auto const& t : m_tools) {
if (t->m_tool != tool || !t->m_current)
continue;
t->resource->sendMotion(wl_fixed_from_double(value.x), wl_fixed_from_double(value.y));
t->m_resource->sendMotion(wl_fixed_from_double(value.x), wl_fixed_from_double(value.y));
t->queueFrame();
}
}
void CTabletV2Protocol::mode(SP<CTabletPad> pad, uint32_t group, uint32_t mode, uint32_t timeMs) {
for (auto const& t : m_vPads) {
if (t->pad != pad)
for (auto const& t : m_pads) {
if (t->m_pad != pad)
continue;
if (t->groups.size() <= group) {
if (t->m_groups.size() <= group) {
LOGM(ERR, "BUG THIS: group >= t->groups.size()");
return;
}
auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(t->resource->client()));
t->groups.at(group)->resource->sendModeSwitch(timeMs, serial, mode);
auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(t->m_resource->client()));
t->m_groups.at(group)->m_resource->sendModeSwitch(timeMs, serial, mode);
}
}
void CTabletV2Protocol::buttonPad(SP<CTabletPad> pad, uint32_t button, uint32_t timeMs, uint32_t state) {
for (auto const& t : m_vPads) {
if (t->pad != pad)
for (auto const& t : m_pads) {
if (t->m_pad != pad)
continue;
t->resource->sendButton(timeMs, button, zwpTabletToolV2ButtonState{state});
t->m_resource->sendButton(timeMs, button, zwpTabletToolV2ButtonState{state});
}
}

View File

@@ -20,10 +20,10 @@ class CTabletPadStripV2Resource {
bool good();
uint32_t id = 0;
uint32_t m_id = 0;
private:
SP<CZwpTabletPadStripV2> resource;
SP<CZwpTabletPadStripV2> m_resource;
friend class CTabletSeat;
friend class CTabletPadGroupV2Resource;
@@ -36,10 +36,10 @@ class CTabletPadRingV2Resource {
bool good();
uint32_t id = 0;
uint32_t m_id = 0;
private:
SP<CZwpTabletPadRingV2> resource;
SP<CZwpTabletPadRingV2> m_resource;
friend class CTabletSeat;
friend class CTabletPadGroupV2Resource;
@@ -50,16 +50,13 @@ class CTabletPadGroupV2Resource {
public:
CTabletPadGroupV2Resource(SP<CZwpTabletPadGroupV2> resource_, size_t idx);
bool good();
void sendData(SP<CTabletPad> pad, SP<Aquamarine::ITabletPad::STabletPadGroup> group);
bool good();
void sendData(SP<CTabletPad> pad, SP<Aquamarine::ITabletPad::STabletPadGroup> group);
std::vector<WP<CTabletPadRingV2Resource>> rings;
std::vector<WP<CTabletPadStripV2Resource>> strips;
size_t idx = 0;
size_t m_idx = 0;
private:
SP<CZwpTabletPadGroupV2> resource;
SP<CZwpTabletPadGroupV2> m_resource;
friend class CTabletSeat;
friend class CTabletPadV2Resource;
@@ -73,15 +70,15 @@ class CTabletPadV2Resource {
bool good();
void sendData();
std::vector<WP<CTabletPadGroupV2Resource>> groups;
std::vector<WP<CTabletPadGroupV2Resource>> m_groups;
WP<CTabletPad> pad;
WP<CTabletSeat> seat;
WP<CTabletPad> m_pad;
WP<CTabletSeat> m_seat;
bool inert = false; // removed was sent
bool m_inert = false; // removed was sent
private:
SP<CZwpTabletPadV2> resource;
SP<CZwpTabletPadV2> m_resource;
void createGroup(SP<Aquamarine::ITabletPad::STabletPadGroup> group, size_t idx);
@@ -96,13 +93,13 @@ class CTabletV2Resource {
bool good();
void sendData();
WP<CTablet> tablet;
WP<CTabletSeat> seat;
WP<CTablet> m_tablet;
WP<CTabletSeat> m_seat;
bool inert = false; // removed was sent
bool m_inert = false; // removed was sent
private:
SP<CZwpTabletV2> resource;
SP<CZwpTabletV2> m_resource;
friend class CTabletSeat;
friend class CTabletV2Protocol;
@@ -118,17 +115,17 @@ class CTabletToolV2Resource {
void queueFrame();
void sendFrame(bool removeSource = true);
bool current = false;
WP<CWLSurfaceResource> lastSurf;
bool m_current = false;
WP<CWLSurfaceResource> m_lastSurf;
WP<CTabletTool> tool;
WP<CTabletSeat> seat;
wl_event_source* frameSource = nullptr;
WP<CTabletTool> m_tool;
WP<CTabletSeat> m_seat;
wl_event_source* m_frameSource = nullptr;
bool inert = false; // removed was sent
bool m_inert = false; // removed was sent
private:
SP<CZwpTabletToolV2> resource;
SP<CZwpTabletToolV2> m_resource;
friend class CTabletSeat;
friend class CTabletV2Protocol;
@@ -141,17 +138,17 @@ class CTabletSeat {
bool good();
void sendData();
std::vector<WP<CTabletToolV2Resource>> tools;
std::vector<WP<CTabletPadV2Resource>> pads;
std::vector<WP<CTabletV2Resource>> tablets;
std::vector<WP<CTabletToolV2Resource>> m_tools;
std::vector<WP<CTabletPadV2Resource>> m_pads;
std::vector<WP<CTabletV2Resource>> m_tablets;
void sendTool(SP<CTabletTool> tool);
void sendPad(SP<CTabletPad> pad);
void sendTablet(SP<CTablet> tablet);
private:
SP<CZwpTabletSeatV2> resource;
WP<CTabletSeat> self;
SP<CZwpTabletSeatV2> m_resource;
WP<CTabletSeat> m_self;
friend class CTabletV2Protocol;
};
@@ -204,19 +201,19 @@ class CTabletV2Protocol : public IWaylandProtocol {
void onGetSeat(CZwpTabletManagerV2* pMgr, uint32_t id, wl_resource* seat);
//
std::vector<UP<CZwpTabletManagerV2>> m_vManagers;
std::vector<SP<CTabletSeat>> m_vSeats;
std::vector<SP<CTabletToolV2Resource>> m_vTools;
std::vector<SP<CTabletV2Resource>> m_vTablets;
std::vector<SP<CTabletPadV2Resource>> m_vPads;
std::vector<SP<CTabletPadGroupV2Resource>> m_vGroups;
std::vector<SP<CTabletPadRingV2Resource>> m_vRings;
std::vector<SP<CTabletPadStripV2Resource>> m_vStrips;
std::vector<UP<CZwpTabletManagerV2>> m_managers;
std::vector<SP<CTabletSeat>> m_seats;
std::vector<SP<CTabletToolV2Resource>> m_tools;
std::vector<SP<CTabletV2Resource>> m_tablets;
std::vector<SP<CTabletPadV2Resource>> m_pads;
std::vector<SP<CTabletPadGroupV2Resource>> m_groups;
std::vector<SP<CTabletPadRingV2Resource>> m_rings;
std::vector<SP<CTabletPadStripV2Resource>> m_strips;
// registered
std::vector<WP<CTablet>> tablets;
std::vector<WP<CTabletTool>> tools;
std::vector<WP<CTabletPad>> pads;
std::vector<WP<CTablet>> m_tabletDevices;
std::vector<WP<CTabletTool>> m_toolDevices;
std::vector<WP<CTabletPad>> m_padDevices;
// FIXME: rings and strips are broken, I don't understand how this shit works.
// It's 2am.

View File

@@ -11,7 +11,7 @@ CTearingControlProtocol::CTearingControlProtocol(const wl_interface* iface, cons
}
void CTearingControlProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeUnique<CWpTearingControlManagerV1>(client, ver, id)).get();
const auto RESOURCE = m_managers.emplace_back(makeUnique<CWpTearingControlManagerV1>(client, ver, id)).get();
RESOURCE->setOnDestroy([this](CWpTearingControlManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setDestroy([this](CWpTearingControlManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
@@ -21,58 +21,58 @@ void CTearingControlProtocol::bindManager(wl_client* client, void* data, uint32_
}
void CTearingControlProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
std::erase_if(m_managers, [&](const auto& other) { return other->resource() == res; });
}
void CTearingControlProtocol::onGetController(wl_client* client, CWpTearingControlManagerV1* pMgr, uint32_t id, SP<CWLSurfaceResource> surf) {
const auto CONTROLLER = m_vTearingControllers.emplace_back(makeUnique<CTearingControl>(makeShared<CWpTearingControlV1>(client, pMgr->version(), id), surf)).get();
const auto CONTROLLER = m_tearingControllers.emplace_back(makeUnique<CTearingControl>(makeShared<CWpTearingControlV1>(client, pMgr->version(), id), surf)).get();
if UNLIKELY (!CONTROLLER->good()) {
pMgr->noMemory();
m_vTearingControllers.pop_back();
m_tearingControllers.pop_back();
return;
}
}
void CTearingControlProtocol::onControllerDestroy(CTearingControl* control) {
std::erase_if(m_vTearingControllers, [control](const auto& other) { return other.get() == control; });
std::erase_if(m_tearingControllers, [control](const auto& other) { return other.get() == control; });
}
void CTearingControlProtocol::onWindowDestroy(PHLWINDOW pWindow) {
for (auto const& c : m_vTearingControllers) {
if (c->pWindow.lock() == pWindow)
c->pWindow.reset();
for (auto const& c : m_tearingControllers) {
if (c->m_window.lock() == pWindow)
c->m_window.reset();
}
}
//
CTearingControl::CTearingControl(SP<CWpTearingControlV1> resource_, SP<CWLSurfaceResource> surf_) : resource(resource_) {
resource->setData(this);
resource->setOnDestroy([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); });
CTearingControl::CTearingControl(SP<CWpTearingControlV1> resource_, SP<CWLSurfaceResource> surf_) : m_resource(resource_) {
m_resource->setData(this);
m_resource->setOnDestroy([this](CWpTearingControlV1* res) { PROTO::tearing->onControllerDestroy(this); });
m_resource->setDestroy([this](CWpTearingControlV1* res) { PROTO::tearing->onControllerDestroy(this); });
m_resource->setSetPresentationHint([this](CWpTearingControlV1* res, wpTearingControlV1PresentationHint hint) { this->onHint(hint); });
for (auto const& w : g_pCompositor->m_windows) {
if (w->m_wlSurface->resource() == surf_) {
pWindow = w;
m_window = w;
break;
}
}
}
void CTearingControl::onHint(wpTearingControlV1PresentationHint hint_) {
hint = hint_;
m_hint = hint_;
updateWindow();
}
void CTearingControl::updateWindow() {
if UNLIKELY (pWindow.expired())
if UNLIKELY (m_window.expired())
return;
pWindow->m_tearingHint = hint == WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC;
m_window->m_tearingHint = m_hint == WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC;
}
bool CTearingControl::good() {
return resource->resource();
return m_resource->resource();
}

View File

@@ -16,19 +16,19 @@ class CTearingControl {
bool good();
bool operator==(const wl_resource* other) const {
return other == resource->resource();
return other == m_resource->resource();
}
bool operator==(const CTearingControl* other) const {
return other->resource == resource;
return other->m_resource == m_resource;
}
private:
void updateWindow();
SP<CWpTearingControlV1> resource;
PHLWINDOWREF pWindow;
wpTearingControlV1PresentationHint hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC;
SP<CWpTearingControlV1> m_resource;
PHLWINDOWREF m_window;
wpTearingControlV1PresentationHint m_hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC;
friend class CTearingControlProtocol;
};
@@ -46,8 +46,8 @@ class CTearingControlProtocol : public IWaylandProtocol {
void onWindowDestroy(PHLWINDOW pWindow);
//
std::vector<UP<CWpTearingControlManagerV1>> m_vManagers;
std::vector<UP<CTearingControl>> m_vTearingControllers;
std::vector<UP<CWpTearingControlManagerV1>> m_managers;
std::vector<UP<CTearingControl>> m_tearingControllers;
friend class CTearingControl;
};

View File

@@ -3,94 +3,94 @@
#include "core/Compositor.hpp"
CTextInputV1::~CTextInputV1() {
events.destroy.emit();
m_events.destroy.emit();
}
CTextInputV1::CTextInputV1(SP<CZwpTextInputV1> resource_) : resource(resource_) {
CTextInputV1::CTextInputV1(SP<CZwpTextInputV1> resource_) : m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setOnDestroy([this](CZwpTextInputV1* pMgr) { PROTO::textInputV1->destroyResource(this); });
m_resource->setOnDestroy([this](CZwpTextInputV1* pMgr) { PROTO::textInputV1->destroyResource(this); });
resource->setActivate([this](CZwpTextInputV1* pMgr, wl_resource* seat, wl_resource* surface) {
m_resource->setActivate([this](CZwpTextInputV1* pMgr, wl_resource* seat, wl_resource* surface) {
if UNLIKELY (!surface) {
LOGM(WARN, "Text-input-v1 PTI{:x}: No surface to activate text input on!", (uintptr_t)this);
return;
}
active = true;
events.enable.emit(CWLSurfaceResource::fromResource(surface));
m_active = true;
m_events.enable.emit(CWLSurfaceResource::fromResource(surface));
});
resource->setDeactivate([this](CZwpTextInputV1* pMgr, wl_resource* seat) {
active = false;
events.disable.emit();
m_resource->setDeactivate([this](CZwpTextInputV1* pMgr, wl_resource* seat) {
m_active = false;
m_events.disable.emit();
});
resource->setReset([this](CZwpTextInputV1* pMgr) {
pendingSurrounding.isPending = false;
pendingContentType.isPending = false;
events.reset.emit();
m_resource->setReset([this](CZwpTextInputV1* pMgr) {
m_pendingSurrounding.isPending = false;
m_pendingContentType.isPending = false;
m_events.reset.emit();
});
resource->setSetSurroundingText(
[this](CZwpTextInputV1* pMgr, const char* text, uint32_t cursor, uint32_t anchor) { pendingSurrounding = {true, std::string(text), cursor, anchor}; });
m_resource->setSetSurroundingText(
[this](CZwpTextInputV1* pMgr, const char* text, uint32_t cursor, uint32_t anchor) { m_pendingSurrounding = {true, std::string(text), cursor, anchor}; });
resource->setSetContentType([this](CZwpTextInputV1* pMgr, uint32_t hint, uint32_t purpose) {
pendingContentType = {true, hint == (uint32_t)ZWP_TEXT_INPUT_V1_CONTENT_HINT_DEFAULT ? (uint32_t)ZWP_TEXT_INPUT_V1_CONTENT_HINT_NONE : hint,
purpose > (uint32_t)ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_PASSWORD ? hint + 1 : hint};
m_resource->setSetContentType([this](CZwpTextInputV1* pMgr, uint32_t hint, uint32_t purpose) {
m_pendingContentType = {true, hint == (uint32_t)ZWP_TEXT_INPUT_V1_CONTENT_HINT_DEFAULT ? (uint32_t)ZWP_TEXT_INPUT_V1_CONTENT_HINT_NONE : hint,
purpose > (uint32_t)ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_PASSWORD ? hint + 1 : hint};
});
resource->setSetCursorRectangle([this](CZwpTextInputV1* pMgr, int32_t x, int32_t y, int32_t width, int32_t height) { cursorRectangle = CBox{x, y, width, height}; });
m_resource->setSetCursorRectangle([this](CZwpTextInputV1* pMgr, int32_t x, int32_t y, int32_t width, int32_t height) { m_cursorRectangle = CBox{x, y, width, height}; });
resource->setCommitState([this](CZwpTextInputV1* pMgr, uint32_t serial_) {
serial = serial_;
events.onCommit.emit();
m_resource->setCommitState([this](CZwpTextInputV1* pMgr, uint32_t serial_) {
m_serial = serial_;
m_events.onCommit.emit();
});
// nothing
resource->setShowInputPanel([](CZwpTextInputV1* pMgr) {});
resource->setHideInputPanel([](CZwpTextInputV1* pMgr) {});
resource->setSetPreferredLanguage([](CZwpTextInputV1* pMgr, const char* language) {});
resource->setInvokeAction([](CZwpTextInputV1* pMgr, uint32_t button, uint32_t index) {});
m_resource->setShowInputPanel([](CZwpTextInputV1* pMgr) {});
m_resource->setHideInputPanel([](CZwpTextInputV1* pMgr) {});
m_resource->setSetPreferredLanguage([](CZwpTextInputV1* pMgr, const char* language) {});
m_resource->setInvokeAction([](CZwpTextInputV1* pMgr, uint32_t button, uint32_t index) {});
}
bool CTextInputV1::good() {
return resource->resource();
return m_resource->resource();
}
wl_client* CTextInputV1::client() {
return resource->client();
return m_resource->client();
}
void CTextInputV1::enter(SP<CWLSurfaceResource> surface) {
resource->sendEnter(surface->getResource()->resource());
active = true;
m_resource->sendEnter(surface->getResource()->resource());
m_active = true;
}
void CTextInputV1::leave() {
resource->sendLeave();
active = false;
m_resource->sendLeave();
m_active = false;
}
void CTextInputV1::preeditCursor(int32_t index) {
resource->sendPreeditCursor(index);
m_resource->sendPreeditCursor(index);
}
void CTextInputV1::preeditStyling(uint32_t index, uint32_t length, zwpTextInputV1PreeditStyle style) {
resource->sendPreeditStyling(index, length, style);
m_resource->sendPreeditStyling(index, length, style);
}
void CTextInputV1::preeditString(uint32_t serial, const char* text, const char* commit) {
resource->sendPreeditString(serial, text, commit);
m_resource->sendPreeditString(serial, text, commit);
}
void CTextInputV1::commitString(uint32_t serial, const char* text) {
resource->sendCommitString(serial, text);
m_resource->sendCommitString(serial, text);
}
void CTextInputV1::deleteSurroundingText(int32_t index, uint32_t length) {
resource->sendDeleteSurroundingText(index, length);
m_resource->sendDeleteSurroundingText(index, length);
}
CTextInputV1Protocol::CTextInputV1Protocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -98,11 +98,11 @@ CTextInputV1Protocol::CTextInputV1Protocol(const wl_interface* iface, const int&
}
void CTextInputV1Protocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeShared<CZwpTextInputManagerV1>(client, ver, id));
const auto RESOURCE = m_managers.emplace_back(makeShared<CZwpTextInputManagerV1>(client, ver, id));
RESOURCE->setOnDestroy([](CZwpTextInputManagerV1* pMgr) { PROTO::textInputV1->destroyResource(pMgr); });
RESOURCE->setCreateTextInput([this](CZwpTextInputManagerV1* pMgr, uint32_t id) {
const auto PTI = m_vClients.emplace_back(makeShared<CTextInputV1>(makeShared<CZwpTextInputV1>(pMgr->client(), pMgr->version(), id)));
const auto PTI = m_clients.emplace_back(makeShared<CTextInputV1>(makeShared<CZwpTextInputV1>(pMgr->client(), pMgr->version(), id)));
LOGM(LOG, "New TI V1 at {:x}", (uintptr_t)PTI.get());
if UNLIKELY (!PTI->good()) {
@@ -112,14 +112,14 @@ void CTextInputV1Protocol::bindManager(wl_client* client, void* data, uint32_t v
return;
}
events.newTextInput.emit(WP<CTextInputV1>(PTI));
m_events.newTextInput.emit(WP<CTextInputV1>(PTI));
});
}
void CTextInputV1Protocol::destroyResource(CTextInputV1* client) {
std::erase_if(m_vClients, [&](const auto& other) { return other.get() == client; });
std::erase_if(m_clients, [&](const auto& other) { return other.get() == client; });
}
void CTextInputV1Protocol::destroyResource(CZwpTextInputManagerV1* client) {
std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == client; });
std::erase_if(m_managers, [&](const auto& other) { return other.get() == client; });
}

View File

@@ -27,11 +27,10 @@ class CTextInputV1 {
wl_client* client();
private:
SP<CZwpTextInputV1> resource;
WP<CTextInputV1> self;
SP<CZwpTextInputV1> m_resource;
uint32_t serial = 0;
bool active = false;
uint32_t m_serial = 0;
bool m_active = false;
struct {
CSignal onCommit;
@@ -39,22 +38,22 @@ class CTextInputV1 {
CSignal disable;
CSignal reset;
CSignal destroy;
} events;
} m_events;
struct SPendingSurr {
bool isPending = false;
std::string text = "";
uint32_t cursor = 0;
uint32_t anchor = 0;
} pendingSurrounding;
} m_pendingSurrounding;
struct SPendingCT {
bool isPending = false;
uint32_t hint = 0;
uint32_t purpose = 0;
} pendingContentType;
} m_pendingContentType;
CBox cursorRectangle = {0, 0, 0, 0};
CBox m_cursorRectangle = {0, 0, 0, 0};
friend class CTextInput;
friend class CTextInputV1Protocol;
@@ -70,11 +69,11 @@ class CTextInputV1Protocol : public IWaylandProtocol {
struct {
CSignal newTextInput; // WP<CTextInputV3>
} events;
} m_events;
private:
std::vector<SP<CZwpTextInputManagerV1>> m_vManagers;
std::vector<SP<CTextInputV1>> m_vClients;
std::vector<SP<CZwpTextInputManagerV1>> m_managers;
std::vector<SP<CTextInputV1>> m_clients;
friend class CTextInputV1;
};

View File

@@ -9,100 +9,100 @@ void CTextInputV3::SState::reset() {
box.updated = false;
}
CTextInputV3::CTextInputV3(SP<CZwpTextInputV3> resource_) : resource(resource_) {
if UNLIKELY (!resource->resource())
CTextInputV3::CTextInputV3(SP<CZwpTextInputV3> resource_) : m_resource(resource_) {
if UNLIKELY (!m_resource->resource())
return;
LOGM(LOG, "New tiv3 at {:016x}", (uintptr_t)this);
resource->setDestroy([this](CZwpTextInputV3* r) { PROTO::textInputV3->destroyTextInput(this); });
resource->setOnDestroy([this](CZwpTextInputV3* r) { PROTO::textInputV3->destroyTextInput(this); });
m_resource->setDestroy([this](CZwpTextInputV3* r) { PROTO::textInputV3->destroyTextInput(this); });
m_resource->setOnDestroy([this](CZwpTextInputV3* r) { PROTO::textInputV3->destroyTextInput(this); });
resource->setCommit([this](CZwpTextInputV3* r) {
bool wasEnabled = current.enabled.value;
m_resource->setCommit([this](CZwpTextInputV3* r) {
bool wasEnabled = m_current.enabled.value;
current = pending;
serial++;
m_current = m_pending;
m_serial++;
if (wasEnabled && !current.enabled.value)
events.disable.emit();
else if (!wasEnabled && current.enabled.value)
events.enable.emit();
else if (current.enabled.value && current.enabled.isEnablePending && current.enabled.isDisablePending)
events.reset.emit();
if (wasEnabled && !m_current.enabled.value)
m_events.disable.emit();
else if (!wasEnabled && m_current.enabled.value)
m_events.enable.emit();
else if (m_current.enabled.value && m_current.enabled.isEnablePending && m_current.enabled.isDisablePending)
m_events.reset.emit();
else
events.onCommit.emit();
m_events.onCommit.emit();
pending.enabled.isEnablePending = false;
pending.enabled.isDisablePending = false;
m_pending.enabled.isEnablePending = false;
m_pending.enabled.isDisablePending = false;
});
resource->setSetSurroundingText([this](CZwpTextInputV3* r, const char* text, int32_t cursor, int32_t anchor) {
pending.surrounding.updated = true;
pending.surrounding.anchor = anchor;
pending.surrounding.cursor = cursor;
pending.surrounding.text = text;
m_resource->setSetSurroundingText([this](CZwpTextInputV3* r, const char* text, int32_t cursor, int32_t anchor) {
m_pending.surrounding.updated = true;
m_pending.surrounding.anchor = anchor;
m_pending.surrounding.cursor = cursor;
m_pending.surrounding.text = text;
});
resource->setSetTextChangeCause([this](CZwpTextInputV3* r, zwpTextInputV3ChangeCause cause) { pending.cause = cause; });
m_resource->setSetTextChangeCause([this](CZwpTextInputV3* r, zwpTextInputV3ChangeCause cause) { m_pending.cause = cause; });
resource->setSetContentType([this](CZwpTextInputV3* r, zwpTextInputV3ContentHint hint, zwpTextInputV3ContentPurpose purpose) {
pending.contentType.updated = true;
pending.contentType.hint = hint;
pending.contentType.purpose = purpose;
m_resource->setSetContentType([this](CZwpTextInputV3* r, zwpTextInputV3ContentHint hint, zwpTextInputV3ContentPurpose purpose) {
m_pending.contentType.updated = true;
m_pending.contentType.hint = hint;
m_pending.contentType.purpose = purpose;
});
resource->setSetCursorRectangle([this](CZwpTextInputV3* r, int32_t x, int32_t y, int32_t w, int32_t h) {
pending.box.updated = true;
pending.box.cursorBox = {x, y, w, h};
m_resource->setSetCursorRectangle([this](CZwpTextInputV3* r, int32_t x, int32_t y, int32_t w, int32_t h) {
m_pending.box.updated = true;
m_pending.box.cursorBox = {x, y, w, h};
});
resource->setEnable([this](CZwpTextInputV3* r) {
pending.reset();
pending.enabled.value = true;
pending.enabled.isEnablePending = true;
m_resource->setEnable([this](CZwpTextInputV3* r) {
m_pending.reset();
m_pending.enabled.value = true;
m_pending.enabled.isEnablePending = true;
});
resource->setDisable([this](CZwpTextInputV3* r) {
pending.enabled.value = false;
pending.enabled.isDisablePending = true;
m_resource->setDisable([this](CZwpTextInputV3* r) {
m_pending.enabled.value = false;
m_pending.enabled.isDisablePending = true;
});
}
CTextInputV3::~CTextInputV3() {
events.destroy.emit();
m_events.destroy.emit();
}
void CTextInputV3::enter(SP<CWLSurfaceResource> surf) {
resource->sendEnter(surf->getResource()->resource());
m_resource->sendEnter(surf->getResource()->resource());
}
void CTextInputV3::leave(SP<CWLSurfaceResource> surf) {
resource->sendLeave(surf->getResource()->resource());
m_resource->sendLeave(surf->getResource()->resource());
}
void CTextInputV3::preeditString(const std::string& text, int32_t cursorBegin, int32_t cursorEnd) {
resource->sendPreeditString(text.c_str(), cursorBegin, cursorEnd);
m_resource->sendPreeditString(text.c_str(), cursorBegin, cursorEnd);
}
void CTextInputV3::commitString(const std::string& text) {
resource->sendCommitString(text.c_str());
m_resource->sendCommitString(text.c_str());
}
void CTextInputV3::deleteSurroundingText(uint32_t beforeLength, uint32_t afterLength) {
resource->sendDeleteSurroundingText(beforeLength, afterLength);
m_resource->sendDeleteSurroundingText(beforeLength, afterLength);
}
void CTextInputV3::sendDone() {
resource->sendDone(serial);
m_resource->sendDone(m_serial);
}
bool CTextInputV3::good() {
return resource->resource();
return m_resource->resource();
}
wl_client* CTextInputV3::client() {
return wl_resource_get_client(resource->resource());
return wl_resource_get_client(m_resource->resource());
}
CTextInputV3Protocol::CTextInputV3Protocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -110,7 +110,7 @@ CTextInputV3Protocol::CTextInputV3Protocol(const wl_interface* iface, const int&
}
void CTextInputV3Protocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeUnique<CZwpTextInputManagerV3>(client, ver, id)).get();
const auto RESOURCE = m_managers.emplace_back(makeUnique<CZwpTextInputManagerV3>(client, ver, id)).get();
RESOURCE->setOnDestroy([this](CZwpTextInputManagerV3* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setDestroy([this](CZwpTextInputManagerV3* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
@@ -118,23 +118,23 @@ void CTextInputV3Protocol::bindManager(wl_client* client, void* data, uint32_t v
}
void CTextInputV3Protocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
std::erase_if(m_managers, [&](const auto& other) { return other->resource() == res; });
}
void CTextInputV3Protocol::destroyTextInput(CTextInputV3* input) {
std::erase_if(m_vTextInputs, [&](const auto& other) { return other.get() == input; });
std::erase_if(m_textInputs, [&](const auto& other) { return other.get() == input; });
}
void CTextInputV3Protocol::onGetTextInput(CZwpTextInputManagerV3* pMgr, uint32_t id, wl_resource* seat) {
const auto CLIENT = pMgr->client();
const auto RESOURCE = m_vTextInputs.emplace_back(makeShared<CTextInputV3>(makeShared<CZwpTextInputV3>(CLIENT, pMgr->version(), id)));
const auto RESOURCE = m_textInputs.emplace_back(makeShared<CTextInputV3>(makeShared<CZwpTextInputV3>(CLIENT, pMgr->version(), id)));
if UNLIKELY (!RESOURCE->good()) {
pMgr->noMemory();
m_vTextInputs.pop_back();
m_textInputs.pop_back();
LOGM(ERR, "Failed to create a tiv3 resource");
return;
}
events.newTextInput.emit(WP<CTextInputV3>(RESOURCE));
m_events.newTextInput.emit(WP<CTextInputV3>(RESOURCE));
}

View File

@@ -32,7 +32,7 @@ class CTextInputV3 {
CSignal disable;
CSignal reset;
CSignal destroy;
} events;
} m_events;
struct SState {
struct {
@@ -63,12 +63,14 @@ class CTextInputV3 {
void reset();
};
SState pending, current;
SState m_pending;
SState m_current;
private:
SP<CZwpTextInputV3> resource;
SP<CZwpTextInputV3> m_resource;
int serial = 0;
int m_serial = 0;
};
class CTextInputV3Protocol : public IWaylandProtocol {
@@ -79,7 +81,7 @@ class CTextInputV3Protocol : public IWaylandProtocol {
struct {
CSignal newTextInput; // WP<CTextInputV3>
} events;
} m_events;
private:
void onManagerResourceDestroy(wl_resource* res);
@@ -87,8 +89,8 @@ class CTextInputV3Protocol : public IWaylandProtocol {
void onGetTextInput(CZwpTextInputManagerV3* pMgr, uint32_t id, wl_resource* seat);
//
std::vector<UP<CZwpTextInputManagerV3>> m_vManagers;
std::vector<SP<CTextInputV3>> m_vTextInputs;
std::vector<UP<CZwpTextInputManagerV3>> m_managers;
std::vector<SP<CTextInputV3>> m_textInputs;
friend class CTextInputV3;
};

View File

@@ -14,120 +14,120 @@
#include <algorithm>
#include <hyprutils/math/Vector2D.hpp>
CToplevelExportClient::CToplevelExportClient(SP<CHyprlandToplevelExportManagerV1> resource_) : resource(resource_) {
CToplevelExportClient::CToplevelExportClient(SP<CHyprlandToplevelExportManagerV1> resource_) : m_resource(resource_) {
if UNLIKELY (!good())
return;
resource->setOnDestroy([this](CHyprlandToplevelExportManagerV1* pMgr) { PROTO::toplevelExport->destroyResource(this); });
resource->setDestroy([this](CHyprlandToplevelExportManagerV1* pMgr) { PROTO::toplevelExport->destroyResource(this); });
resource->setCaptureToplevel([this](CHyprlandToplevelExportManagerV1* pMgr, uint32_t frame, int32_t overlayCursor, uint32_t handle) {
m_resource->setOnDestroy([this](CHyprlandToplevelExportManagerV1* pMgr) { PROTO::toplevelExport->destroyResource(this); });
m_resource->setDestroy([this](CHyprlandToplevelExportManagerV1* pMgr) { PROTO::toplevelExport->destroyResource(this); });
m_resource->setCaptureToplevel([this](CHyprlandToplevelExportManagerV1* pMgr, uint32_t frame, int32_t overlayCursor, uint32_t handle) {
this->captureToplevel(pMgr, frame, overlayCursor, g_pCompositor->getWindowFromHandle(handle));
});
resource->setCaptureToplevelWithWlrToplevelHandle([this](CHyprlandToplevelExportManagerV1* pMgr, uint32_t frame, int32_t overlayCursor, wl_resource* handle) {
m_resource->setCaptureToplevelWithWlrToplevelHandle([this](CHyprlandToplevelExportManagerV1* pMgr, uint32_t frame, int32_t overlayCursor, wl_resource* handle) {
this->captureToplevel(pMgr, frame, overlayCursor, PROTO::foreignToplevelWlr->windowFromHandleResource(handle));
});
lastMeasure.reset();
lastFrame.reset();
tickCallback = g_pHookSystem->hookDynamic("tick", [&](void* self, SCallbackInfo& info, std::any data) { onTick(); });
m_lastMeasure.reset();
m_lastFrame.reset();
m_tickCallback = g_pHookSystem->hookDynamic("tick", [&](void* self, SCallbackInfo& info, std::any data) { onTick(); });
}
void CToplevelExportClient::captureToplevel(CHyprlandToplevelExportManagerV1* pMgr, uint32_t frame, int32_t overlayCursor_, PHLWINDOW handle) {
// create a frame
const auto FRAME = PROTO::toplevelExport->m_vFrames.emplace_back(
makeShared<CToplevelExportFrame>(makeShared<CHyprlandToplevelExportFrameV1>(resource->client(), resource->version(), frame), overlayCursor_, handle));
const auto FRAME = PROTO::toplevelExport->m_frames.emplace_back(
makeShared<CToplevelExportFrame>(makeShared<CHyprlandToplevelExportFrameV1>(m_resource->client(), m_resource->version(), frame), overlayCursor_, handle));
if UNLIKELY (!FRAME->good()) {
LOGM(ERR, "Couldn't alloc frame for sharing! (no memory)");
resource->noMemory();
m_resource->noMemory();
PROTO::toplevelExport->destroyResource(FRAME.get());
return;
}
FRAME->self = FRAME;
FRAME->client = self;
FRAME->m_self = FRAME;
FRAME->m_client = m_self;
}
void CToplevelExportClient::onTick() {
if (lastMeasure.getMillis() < 500)
if (m_lastMeasure.getMillis() < 500)
return;
framesInLastHalfSecond = frameCounter;
frameCounter = 0;
lastMeasure.reset();
m_framesInLastHalfSecond = m_frameCounter;
m_frameCounter = 0;
m_lastMeasure.reset();
const auto LASTFRAMEDELTA = lastFrame.getMillis() / 1000.0;
const bool FRAMEAWAITING = std::ranges::any_of(PROTO::toplevelExport->m_vFrames, [&](const auto& frame) { return frame->client.get() == this; });
const auto LASTFRAMEDELTA = m_lastFrame.getMillis() / 1000.0;
const bool FRAMEAWAITING = std::ranges::any_of(PROTO::toplevelExport->m_frames, [&](const auto& frame) { return frame->m_client.get() == this; });
if (framesInLastHalfSecond > 3 && !sentScreencast) {
EMIT_HOOK_EVENT("screencast", (std::vector<uint64_t>{1, (uint64_t)framesInLastHalfSecond, (uint64_t)clientOwner}));
g_pEventManager->postEvent(SHyprIPCEvent{"screencast", "1," + std::to_string(clientOwner)});
sentScreencast = true;
} else if (framesInLastHalfSecond < 4 && sentScreencast && LASTFRAMEDELTA > 1.0 && !FRAMEAWAITING) {
EMIT_HOOK_EVENT("screencast", (std::vector<uint64_t>{0, (uint64_t)framesInLastHalfSecond, (uint64_t)clientOwner}));
g_pEventManager->postEvent(SHyprIPCEvent{"screencast", "0," + std::to_string(clientOwner)});
sentScreencast = false;
if (m_framesInLastHalfSecond > 3 && !m_sentScreencast) {
EMIT_HOOK_EVENT("screencast", (std::vector<uint64_t>{1, (uint64_t)m_framesInLastHalfSecond, (uint64_t)m_clientOwner}));
g_pEventManager->postEvent(SHyprIPCEvent{"screencast", "1," + std::to_string(m_clientOwner)});
m_sentScreencast = true;
} else if (m_framesInLastHalfSecond < 4 && m_sentScreencast && LASTFRAMEDELTA > 1.0 && !FRAMEAWAITING) {
EMIT_HOOK_EVENT("screencast", (std::vector<uint64_t>{0, (uint64_t)m_framesInLastHalfSecond, (uint64_t)m_clientOwner}));
g_pEventManager->postEvent(SHyprIPCEvent{"screencast", "0," + std::to_string(m_clientOwner)});
m_sentScreencast = false;
}
}
bool CToplevelExportClient::good() {
return resource->resource();
return m_resource->resource();
}
CToplevelExportFrame::CToplevelExportFrame(SP<CHyprlandToplevelExportFrameV1> resource_, int32_t overlayCursor_, PHLWINDOW pWindow_) : resource(resource_), pWindow(pWindow_) {
CToplevelExportFrame::CToplevelExportFrame(SP<CHyprlandToplevelExportFrameV1> resource_, int32_t overlayCursor_, PHLWINDOW pWindow_) : m_resource(resource_), m_window(pWindow_) {
if UNLIKELY (!good())
return;
cursorOverlayRequested = !!overlayCursor_;
m_cursorOverlayRequested = !!overlayCursor_;
if UNLIKELY (!pWindow) {
LOGM(ERR, "Client requested sharing of window handle {:x} which does not exist!", pWindow);
resource->sendFailed();
if UNLIKELY (!m_window) {
LOGM(ERR, "Client requested sharing of window handle {:x} which does not exist!", m_window);
m_resource->sendFailed();
return;
}
if UNLIKELY (!pWindow->m_isMapped) {
LOGM(ERR, "Client requested sharing of window handle {:x} which is not shareable!", pWindow);
resource->sendFailed();
if UNLIKELY (!m_window->m_isMapped) {
LOGM(ERR, "Client requested sharing of window handle {:x} which is not shareable!", m_window);
m_resource->sendFailed();
return;
}
resource->setOnDestroy([this](CHyprlandToplevelExportFrameV1* pFrame) { PROTO::toplevelExport->destroyResource(this); });
resource->setDestroy([this](CHyprlandToplevelExportFrameV1* pFrame) { PROTO::toplevelExport->destroyResource(this); });
resource->setCopy([this](CHyprlandToplevelExportFrameV1* pFrame, wl_resource* res, int32_t ignoreDamage) { this->copy(pFrame, res, ignoreDamage); });
m_resource->setOnDestroy([this](CHyprlandToplevelExportFrameV1* pFrame) { PROTO::toplevelExport->destroyResource(this); });
m_resource->setDestroy([this](CHyprlandToplevelExportFrameV1* pFrame) { PROTO::toplevelExport->destroyResource(this); });
m_resource->setCopy([this](CHyprlandToplevelExportFrameV1* pFrame, wl_resource* res, int32_t ignoreDamage) { this->copy(pFrame, res, ignoreDamage); });
const auto PMONITOR = pWindow->m_monitor.lock();
const auto PMONITOR = m_window->m_monitor.lock();
g_pHyprRenderer->makeEGLCurrent();
shmFormat = g_pHyprOpenGL->getPreferredReadFormat(PMONITOR);
if UNLIKELY (shmFormat == DRM_FORMAT_INVALID) {
m_shmFormat = g_pHyprOpenGL->getPreferredReadFormat(PMONITOR);
if UNLIKELY (m_shmFormat == DRM_FORMAT_INVALID) {
LOGM(ERR, "No format supported by renderer in capture toplevel");
resource->sendFailed();
m_resource->sendFailed();
return;
}
const auto PSHMINFO = NFormatUtils::getPixelFormatFromDRM(shmFormat);
const auto PSHMINFO = NFormatUtils::getPixelFormatFromDRM(m_shmFormat);
if UNLIKELY (!PSHMINFO) {
LOGM(ERR, "No pixel format supported by renderer in capture toplevel");
resource->sendFailed();
m_resource->sendFailed();
return;
}
dmabufFormat = PMONITOR->m_output->state->state().drmFormat;
m_dmabufFormat = PMONITOR->m_output->state->state().drmFormat;
box = {0, 0, (int)(pWindow->m_realSize->value().x * PMONITOR->m_scale), (int)(pWindow->m_realSize->value().y * PMONITOR->m_scale)};
m_box = {0, 0, (int)(m_window->m_realSize->value().x * PMONITOR->m_scale), (int)(m_window->m_realSize->value().y * PMONITOR->m_scale)};
box.transform(wlTransformToHyprutils(PMONITOR->m_transform), PMONITOR->m_transformedSize.x, PMONITOR->m_transformedSize.y).round();
m_box.transform(wlTransformToHyprutils(PMONITOR->m_transform), PMONITOR->m_transformedSize.x, PMONITOR->m_transformedSize.y).round();
shmStride = NFormatUtils::minStride(PSHMINFO, box.w);
m_shmStride = NFormatUtils::minStride(PSHMINFO, m_box.w);
resource->sendBuffer(NFormatUtils::drmToShm(shmFormat), box.width, box.height, shmStride);
m_resource->sendBuffer(NFormatUtils::drmToShm(m_shmFormat), m_box.width, m_box.height, m_shmStride);
if LIKELY (dmabufFormat != DRM_FORMAT_INVALID)
resource->sendLinuxDmabuf(dmabufFormat, box.width, box.height);
if LIKELY (m_dmabufFormat != DRM_FORMAT_INVALID)
m_resource->sendLinuxDmabuf(m_dmabufFormat, m_box.width, m_box.height);
resource->sendBufferDone();
m_resource->sendBufferDone();
}
void CToplevelExportFrame::copy(CHyprlandToplevelExportFrameV1* pFrame, wl_resource* buffer_, int32_t ignoreDamage) {
@@ -136,106 +136,106 @@ void CToplevelExportFrame::copy(CHyprlandToplevelExportFrameV1* pFrame, wl_resou
return;
}
if UNLIKELY (!validMapped(pWindow)) {
LOGM(ERR, "Client requested sharing of window handle {:x} which is gone!", pWindow);
resource->sendFailed();
if UNLIKELY (!validMapped(m_window)) {
LOGM(ERR, "Client requested sharing of window handle {:x} which is gone!", m_window);
m_resource->sendFailed();
return;
}
if UNLIKELY (!pWindow->m_isMapped) {
LOGM(ERR, "Client requested sharing of window handle {:x} which is not shareable (2)!", pWindow);
resource->sendFailed();
if UNLIKELY (!m_window->m_isMapped) {
LOGM(ERR, "Client requested sharing of window handle {:x} which is not shareable (2)!", m_window);
m_resource->sendFailed();
return;
}
const auto PBUFFER = CWLBufferResource::fromResource(buffer_);
if UNLIKELY (!PBUFFER) {
resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer");
m_resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer");
PROTO::toplevelExport->destroyResource(this);
return;
}
if UNLIKELY (PBUFFER->m_buffer->size != box.size()) {
resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer dimensions");
if UNLIKELY (PBUFFER->m_buffer->size != m_box.size()) {
m_resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer dimensions");
PROTO::toplevelExport->destroyResource(this);
return;
}
if UNLIKELY (buffer) {
resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_ALREADY_USED, "frame already used");
if UNLIKELY (m_buffer) {
m_resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_ALREADY_USED, "frame already used");
PROTO::toplevelExport->destroyResource(this);
return;
}
if (auto attrs = PBUFFER->m_buffer->dmabuf(); attrs.success) {
bufferDMA = true;
m_bufferDMA = true;
if (attrs.format != dmabufFormat) {
resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
if (attrs.format != m_dmabufFormat) {
m_resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
PROTO::toplevelExport->destroyResource(this);
return;
}
} else if (auto attrs = PBUFFER->m_buffer->shm(); attrs.success) {
if (attrs.format != shmFormat) {
resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
if (attrs.format != m_shmFormat) {
m_resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
PROTO::toplevelExport->destroyResource(this);
return;
} else if ((int)attrs.stride != shmStride) {
resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer stride");
} else if ((int)attrs.stride != m_shmStride) {
m_resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer stride");
PROTO::toplevelExport->destroyResource(this);
return;
}
} else {
resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer type");
m_resource->error(HYPRLAND_TOPLEVEL_EXPORT_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer type");
PROTO::toplevelExport->destroyResource(this);
return;
}
buffer = CHLBufferReference(PBUFFER->m_buffer.lock());
m_buffer = CHLBufferReference(PBUFFER->m_buffer.lock());
m_ignoreDamage = ignoreDamage;
if (ignoreDamage && validMapped(pWindow))
if (ignoreDamage && validMapped(m_window))
share();
else
PROTO::toplevelExport->m_vFramesAwaitingWrite.emplace_back(self);
PROTO::toplevelExport->m_framesAwaitingWrite.emplace_back(m_self);
}
void CToplevelExportFrame::share() {
if (!buffer || !validMapped(pWindow))
if (!m_buffer || !validMapped(m_window))
return;
if (bufferDMA) {
if (m_bufferDMA) {
if (!copyDmabuf(Time::steadyNow())) {
resource->sendFailed();
m_resource->sendFailed();
return;
}
} else {
if (!copyShm(Time::steadyNow())) {
resource->sendFailed();
m_resource->sendFailed();
return;
}
}
resource->sendFlags((hyprlandToplevelExportFrameV1Flags)0);
m_resource->sendFlags((hyprlandToplevelExportFrameV1Flags)0);
if (!m_ignoreDamage)
resource->sendDamage(0, 0, box.width, box.height);
m_resource->sendDamage(0, 0, m_box.width, m_box.height);
const auto [sec, nsec] = Time::secNsec(Time::steadyNow());
uint32_t tvSecHi = (sizeof(sec) > 4) ? sec >> 32 : 0;
uint32_t tvSecLo = sec & 0xFFFFFFFF;
resource->sendReady(tvSecHi, tvSecLo, nsec);
m_resource->sendReady(tvSecHi, tvSecLo, nsec);
}
bool CToplevelExportFrame::copyShm(const Time::steady_tp& now) {
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(resource->client(), PERMISSION_TYPE_SCREENCOPY);
auto shm = buffer->shm();
auto [pixelData, fmt, bufLen] = buffer->beginDataPtr(0); // no need for end, cuz it's shm
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
auto shm = m_buffer->shm();
auto [pixelData, fmt, bufLen] = m_buffer->beginDataPtr(0); // no need for end, cuz it's shm
// render the client
const auto PMONITOR = pWindow->m_monitor.lock();
const auto PMONITOR = m_window->m_monitor.lock();
CRegion fakeDamage{0, 0, PMONITOR->m_pixelSize.x * 10, PMONITOR->m_pixelSize.y * 10};
g_pHyprRenderer->makeEGLCurrent();
@@ -257,12 +257,12 @@ bool CToplevelExportFrame::copyShm(const Time::steady_tp& now) {
// render client at 0,0
if (PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW) {
g_pHyprRenderer->m_bBlockSurfaceFeedback = g_pHyprRenderer->shouldRenderWindow(pWindow); // block the feedback to avoid spamming the surface if it's visible
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, now, false, RENDER_PASS_ALL, true, true);
g_pHyprRenderer->m_bBlockSurfaceFeedback = g_pHyprRenderer->shouldRenderWindow(m_window); // block the feedback to avoid spamming the surface if it's visible
g_pHyprRenderer->renderWindow(m_window, PMONITOR, now, false, RENDER_PASS_ALL, true, true);
g_pHyprRenderer->m_bBlockSurfaceFeedback = false;
if (overlayCursor)
g_pPointerManager->renderSoftwareCursorsFor(PMONITOR->m_self.lock(), now, fakeDamage, g_pInputManager->getMouseCoordsInternal() - pWindow->m_realPosition->value());
g_pPointerManager->renderSoftwareCursorsFor(PMONITOR->m_self.lock(), now, fakeDamage, g_pInputManager->getMouseCoordsInternal() - m_window->m_realPosition->value());
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_DENY) {
CBox texbox =
CBox{PMONITOR->m_transformedSize / 2.F, g_pHyprOpenGL->m_pScreencopyDeniedTexture->m_vSize}.translate(-g_pHyprOpenGL->m_pScreencopyDeniedTexture->m_vSize / 2.F);
@@ -294,24 +294,24 @@ bool CToplevelExportFrame::copyShm(const Time::steady_tp& now) {
switch (PMONITOR->m_transform) {
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
case WL_OUTPUT_TRANSFORM_90: {
origin.y = PMONITOR->m_pixelSize.y - box.height;
origin.y = PMONITOR->m_pixelSize.y - m_box.height;
break;
}
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
case WL_OUTPUT_TRANSFORM_180: {
origin.x = PMONITOR->m_pixelSize.x - box.width;
origin.y = PMONITOR->m_pixelSize.y - box.height;
origin.x = PMONITOR->m_pixelSize.x - m_box.width;
origin.y = PMONITOR->m_pixelSize.y - m_box.height;
break;
}
case WL_OUTPUT_TRANSFORM_FLIPPED:
case WL_OUTPUT_TRANSFORM_270: {
origin.x = PMONITOR->m_pixelSize.x - box.width;
origin.x = PMONITOR->m_pixelSize.x - m_box.width;
break;
}
default: break;
}
glReadPixels(origin.x, origin.y, box.width, box.height, glFormat, PFORMAT->glType, pixelData);
glReadPixels(origin.x, origin.y, m_box.width, m_box.height, glFormat, PFORMAT->glType, pixelData);
if (overlayCursor) {
g_pPointerManager->unlockSoftwareForMonitor(PMONITOR->m_self.lock());
@@ -328,8 +328,8 @@ bool CToplevelExportFrame::copyShm(const Time::steady_tp& now) {
}
bool CToplevelExportFrame::copyDmabuf(const Time::steady_tp& now) {
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(resource->client(), PERMISSION_TYPE_SCREENCOPY);
const auto PMONITOR = pWindow->m_monitor.lock();
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
const auto PMONITOR = m_window->m_monitor.lock();
CRegion fakeDamage{0, 0, INT16_MAX, INT16_MAX};
@@ -340,17 +340,17 @@ bool CToplevelExportFrame::copyDmabuf(const Time::steady_tp& now) {
g_pPointerManager->damageCursor(PMONITOR->m_self.lock());
}
if (!g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_TO_BUFFER, buffer.m_buffer))
if (!g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_TO_BUFFER, m_buffer.m_buffer))
return false;
g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 1.0));
if (PERM == PERMISSION_RULE_ALLOW_MODE_ALLOW) {
g_pHyprRenderer->m_bBlockSurfaceFeedback = g_pHyprRenderer->shouldRenderWindow(pWindow); // block the feedback to avoid spamming the surface if it's visible
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, now, false, RENDER_PASS_ALL, true, true);
g_pHyprRenderer->m_bBlockSurfaceFeedback = g_pHyprRenderer->shouldRenderWindow(m_window); // block the feedback to avoid spamming the surface if it's visible
g_pHyprRenderer->renderWindow(m_window, PMONITOR, now, false, RENDER_PASS_ALL, true, true);
g_pHyprRenderer->m_bBlockSurfaceFeedback = false;
if (overlayCursor)
g_pPointerManager->renderSoftwareCursorsFor(PMONITOR->m_self.lock(), now, fakeDamage, g_pInputManager->getMouseCoordsInternal() - pWindow->m_realPosition->value());
g_pPointerManager->renderSoftwareCursorsFor(PMONITOR->m_self.lock(), now, fakeDamage, g_pInputManager->getMouseCoordsInternal() - m_window->m_realPosition->value());
} else if (PERM == PERMISSION_RULE_ALLOW_MODE_DENY) {
CBox texbox =
CBox{PMONITOR->m_transformedSize / 2.F, g_pHyprOpenGL->m_pScreencopyDeniedTexture->m_vSize}.translate(-g_pHyprOpenGL->m_pScreencopyDeniedTexture->m_vSize / 2.F);
@@ -369,7 +369,7 @@ bool CToplevelExportFrame::copyDmabuf(const Time::steady_tp& now) {
}
bool CToplevelExportFrame::shouldOverlayCursor() const {
if (!cursorOverlayRequested)
if (!m_cursorOverlayRequested)
return false;
auto pointerSurfaceResource = g_pSeatManager->m_state.pointerFocus.lock();
@@ -379,11 +379,11 @@ bool CToplevelExportFrame::shouldOverlayCursor() const {
auto pointerSurface = CWLSurface::fromResource(pointerSurfaceResource);
return pointerSurface && pointerSurface->getWindow() == pWindow;
return pointerSurface && pointerSurface->getWindow() == m_window;
}
bool CToplevelExportFrame::good() {
return resource->resource();
return m_resource->resource();
}
CToplevelExportProtocol::CToplevelExportProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@@ -391,59 +391,59 @@ CToplevelExportProtocol::CToplevelExportProtocol(const wl_interface* iface, cons
}
void CToplevelExportProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto CLIENT = m_vClients.emplace_back(makeShared<CToplevelExportClient>(makeShared<CHyprlandToplevelExportManagerV1>(client, ver, id)));
const auto CLIENT = m_clients.emplace_back(makeShared<CToplevelExportClient>(makeShared<CHyprlandToplevelExportManagerV1>(client, ver, id)));
if (!CLIENT->good()) {
LOGM(LOG, "Failed to bind client! (out of memory)");
wl_client_post_no_memory(client);
m_vClients.pop_back();
m_clients.pop_back();
return;
}
CLIENT->self = CLIENT;
CLIENT->m_self = CLIENT;
LOGM(LOG, "Bound client successfully!");
}
void CToplevelExportProtocol::destroyResource(CToplevelExportClient* client) {
std::erase_if(m_vClients, [&](const auto& other) { return other.get() == client; });
std::erase_if(m_vFrames, [&](const auto& other) { return other->client.get() == client; });
std::erase_if(m_vFramesAwaitingWrite, [&](const auto& other) { return !other || other->client.get() == client; });
std::erase_if(m_clients, [&](const auto& other) { return other.get() == client; });
std::erase_if(m_frames, [&](const auto& other) { return other->m_client.get() == client; });
std::erase_if(m_framesAwaitingWrite, [&](const auto& other) { return !other || other->m_client.get() == client; });
}
void CToplevelExportProtocol::destroyResource(CToplevelExportFrame* frame) {
std::erase_if(m_vFrames, [&](const auto& other) { return other.get() == frame; });
std::erase_if(m_vFramesAwaitingWrite, [&](const auto& other) { return !other || other.get() == frame; });
std::erase_if(m_frames, [&](const auto& other) { return other.get() == frame; });
std::erase_if(m_framesAwaitingWrite, [&](const auto& other) { return !other || other.get() == frame; });
}
void CToplevelExportProtocol::onOutputCommit(PHLMONITOR pMonitor) {
if (m_vFramesAwaitingWrite.empty())
if (m_framesAwaitingWrite.empty())
return; // nothing to share
std::vector<WP<CToplevelExportFrame>> framesToRemove;
// reserve number of elements to avoid reallocations
framesToRemove.reserve(m_vFramesAwaitingWrite.size());
framesToRemove.reserve(m_framesAwaitingWrite.size());
// share frame if correct output
for (auto const& f : m_vFramesAwaitingWrite) {
for (auto const& f : m_framesAwaitingWrite) {
if (!f)
continue;
// check permissions
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(f->resource->client(), PERMISSION_TYPE_SCREENCOPY);
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(f->m_resource->client(), PERMISSION_TYPE_SCREENCOPY);
if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING)
continue; // pending an answer, don't do anything yet.
if (!validMapped(f->pWindow)) {
if (!validMapped(f->m_window)) {
framesToRemove.emplace_back(f);
continue;
}
if (!f->pWindow)
if (!f->m_window)
continue;
const auto PWINDOW = f->pWindow;
const auto PWINDOW = f->m_window;
if (pMonitor != PWINDOW->m_monitor.lock())
continue;
@@ -455,20 +455,20 @@ void CToplevelExportProtocol::onOutputCommit(PHLMONITOR pMonitor) {
f->share();
f->client->lastFrame.reset();
++f->client->frameCounter;
f->m_client->m_lastFrame.reset();
++f->m_client->m_frameCounter;
framesToRemove.push_back(f);
}
for (auto const& f : framesToRemove) {
std::erase(m_vFramesAwaitingWrite, f);
std::erase(m_framesAwaitingWrite, f);
}
}
void CToplevelExportProtocol::onWindowUnmap(PHLWINDOW pWindow) {
for (auto const& f : m_vFrames) {
if (f->pWindow == pWindow)
f->pWindow.reset();
for (auto const& f : m_frames) {
if (f->m_window == pWindow)
f->m_window.reset();
}
}

View File

@@ -17,20 +17,20 @@ class CToplevelExportClient {
bool good();
WP<CToplevelExportClient> self;
eClientOwners clientOwner = CLIENT_TOPLEVEL_EXPORT;
WP<CToplevelExportClient> m_self;
eClientOwners m_clientOwner = CLIENT_TOPLEVEL_EXPORT;
CTimer lastFrame;
int frameCounter = 0;
CTimer m_lastFrame;
int m_frameCounter = 0;
private:
SP<CHyprlandToplevelExportManagerV1> resource;
SP<CHyprlandToplevelExportManagerV1> m_resource;
int framesInLastHalfSecond = 0;
CTimer lastMeasure;
bool sentScreencast = false;
int m_framesInLastHalfSecond = 0;
CTimer m_lastMeasure;
bool m_sentScreencast = false;
SP<HOOK_CALLBACK_FN> tickCallback;
SP<HOOK_CALLBACK_FN> m_tickCallback;
void onTick();
void captureToplevel(CHyprlandToplevelExportManagerV1* pMgr, uint32_t frame, int32_t overlayCursor, PHLWINDOW handle);
@@ -44,23 +44,22 @@ class CToplevelExportFrame {
bool good();
WP<CToplevelExportFrame> self;
WP<CToplevelExportClient> client;
WP<CToplevelExportFrame> m_self;
WP<CToplevelExportClient> m_client;
private:
SP<CHyprlandToplevelExportFrameV1> resource;
SP<CHyprlandToplevelExportFrameV1> m_resource;
PHLWINDOW pWindow;
bool cursorOverlayRequested = false;
bool m_ignoreDamage = false;
bool lockedSWCursors = false;
PHLWINDOW m_window;
bool m_cursorOverlayRequested = false;
bool m_ignoreDamage = false;
CHLBufferReference buffer;
bool bufferDMA = false;
uint32_t shmFormat = 0;
uint32_t dmabufFormat = 0;
int shmStride = 0;
CBox box = {};
CHLBufferReference m_buffer;
bool m_bufferDMA = false;
uint32_t m_shmFormat = 0;
uint32_t m_dmabufFormat = 0;
int m_shmStride = 0;
CBox m_box = {};
void copy(CHyprlandToplevelExportFrameV1* pFrame, wl_resource* buffer, int32_t ignoreDamage);
bool copyDmabuf(const Time::steady_tp& now);
@@ -83,9 +82,9 @@ class CToplevelExportProtocol : IWaylandProtocol {
void onOutputCommit(PHLMONITOR pMonitor);
private:
std::vector<SP<CToplevelExportClient>> m_vClients;
std::vector<SP<CToplevelExportFrame>> m_vFrames;
std::vector<WP<CToplevelExportFrame>> m_vFramesAwaitingWrite;
std::vector<SP<CToplevelExportClient>> m_clients;
std::vector<SP<CToplevelExportFrame>> m_frames;
std::vector<WP<CToplevelExportFrame>> m_framesAwaitingWrite;
void shareFrame(CToplevelExportFrame* frame);
bool copyFrameDmabuf(CToplevelExportFrame* frame, const Time::steady_tp& now);

View File

@@ -3,76 +3,76 @@
#include "ForeignToplevelWlr.hpp"
#include "ForeignToplevel.hpp"
CToplevelWindowMappingHandle::CToplevelWindowMappingHandle(SP<CHyprlandToplevelWindowMappingHandleV1> resource_) : resource(resource_) {}
CToplevelWindowMappingHandle::CToplevelWindowMappingHandle(SP<CHyprlandToplevelWindowMappingHandleV1> resource_) : m_resource(resource_) {}
CToplevelMappingManager::CToplevelMappingManager(SP<CHyprlandToplevelMappingManagerV1> resource_) : resource(resource_) {
CToplevelMappingManager::CToplevelMappingManager(SP<CHyprlandToplevelMappingManagerV1> resource_) : m_resource(resource_) {
if UNLIKELY (!resource_->resource())
return;
resource->setOnDestroy([this](CHyprlandToplevelMappingManagerV1* h) { PROTO::toplevelMapping->onManagerResourceDestroy(this); });
resource->setDestroy([this](CHyprlandToplevelMappingManagerV1* h) { PROTO::toplevelMapping->onManagerResourceDestroy(this); });
m_resource->setOnDestroy([this](CHyprlandToplevelMappingManagerV1* h) { PROTO::toplevelMapping->onManagerResourceDestroy(this); });
m_resource->setDestroy([this](CHyprlandToplevelMappingManagerV1* h) { PROTO::toplevelMapping->onManagerResourceDestroy(this); });
resource->setGetWindowForToplevel([this](CHyprlandToplevelMappingManagerV1* mgr, uint32_t handle, wl_resource* toplevel) {
const auto NEWHANDLE = PROTO::toplevelMapping->m_vHandles.emplace_back(
makeShared<CToplevelWindowMappingHandle>(makeShared<CHyprlandToplevelWindowMappingHandleV1>(resource->client(), resource->version(), handle)));
m_resource->setGetWindowForToplevel([this](CHyprlandToplevelMappingManagerV1* mgr, uint32_t handle, wl_resource* toplevel) {
const auto NEWHANDLE = PROTO::toplevelMapping->m_handles.emplace_back(
makeShared<CToplevelWindowMappingHandle>(makeShared<CHyprlandToplevelWindowMappingHandleV1>(m_resource->client(), m_resource->version(), handle)));
if UNLIKELY (!NEWHANDLE->resource->resource()) {
if UNLIKELY (!NEWHANDLE->m_resource->resource()) {
LOGM(ERR, "Couldn't alloc mapping handle! (no memory)");
resource->noMemory();
m_resource->noMemory();
return;
}
NEWHANDLE->resource->setOnDestroy([](CHyprlandToplevelWindowMappingHandleV1* h) { PROTO::toplevelMapping->destroyHandle(h); });
NEWHANDLE->resource->setDestroy([](CHyprlandToplevelWindowMappingHandleV1* h) { PROTO::toplevelMapping->destroyHandle(h); });
NEWHANDLE->m_resource->setOnDestroy([](CHyprlandToplevelWindowMappingHandleV1* h) { PROTO::toplevelMapping->destroyHandle(h); });
NEWHANDLE->m_resource->setDestroy([](CHyprlandToplevelWindowMappingHandleV1* h) { PROTO::toplevelMapping->destroyHandle(h); });
const auto WINDOW = PROTO::foreignToplevel->windowFromHandleResource(toplevel);
if (!WINDOW)
NEWHANDLE->resource->sendFailed();
NEWHANDLE->m_resource->sendFailed();
else
NEWHANDLE->resource->sendWindowAddress((uint64_t)WINDOW.get() >> 32 & 0xFFFFFFFF, (uint64_t)WINDOW.get() & 0xFFFFFFFF);
NEWHANDLE->m_resource->sendWindowAddress((uint64_t)WINDOW.get() >> 32 & 0xFFFFFFFF, (uint64_t)WINDOW.get() & 0xFFFFFFFF);
});
resource->setGetWindowForToplevelWlr([this](CHyprlandToplevelMappingManagerV1* mgr, uint32_t handle, wl_resource* toplevel) {
const auto NEWHANDLE = PROTO::toplevelMapping->m_vHandles.emplace_back(
makeShared<CToplevelWindowMappingHandle>(makeShared<CHyprlandToplevelWindowMappingHandleV1>(resource->client(), resource->version(), handle)));
m_resource->setGetWindowForToplevelWlr([this](CHyprlandToplevelMappingManagerV1* mgr, uint32_t handle, wl_resource* toplevel) {
const auto NEWHANDLE = PROTO::toplevelMapping->m_handles.emplace_back(
makeShared<CToplevelWindowMappingHandle>(makeShared<CHyprlandToplevelWindowMappingHandleV1>(m_resource->client(), m_resource->version(), handle)));
if UNLIKELY (!NEWHANDLE->resource->resource()) {
if UNLIKELY (!NEWHANDLE->m_resource->resource()) {
LOGM(ERR, "Couldn't alloc mapping handle! (no memory)");
resource->noMemory();
m_resource->noMemory();
return;
}
NEWHANDLE->resource->setOnDestroy([](CHyprlandToplevelWindowMappingHandleV1* h) { PROTO::toplevelMapping->destroyHandle(h); });
NEWHANDLE->resource->setDestroy([](CHyprlandToplevelWindowMappingHandleV1* h) { PROTO::toplevelMapping->destroyHandle(h); });
NEWHANDLE->m_resource->setOnDestroy([](CHyprlandToplevelWindowMappingHandleV1* h) { PROTO::toplevelMapping->destroyHandle(h); });
NEWHANDLE->m_resource->setDestroy([](CHyprlandToplevelWindowMappingHandleV1* h) { PROTO::toplevelMapping->destroyHandle(h); });
const auto WINDOW = PROTO::foreignToplevelWlr->windowFromHandleResource(toplevel);
if (!WINDOW)
NEWHANDLE->resource->sendFailed();
NEWHANDLE->m_resource->sendFailed();
else
NEWHANDLE->resource->sendWindowAddress((uint64_t)WINDOW.get() >> 32 & 0xFFFFFFFF, (uint64_t)WINDOW.get() & 0xFFFFFFFF);
NEWHANDLE->m_resource->sendWindowAddress((uint64_t)WINDOW.get() >> 32 & 0xFFFFFFFF, (uint64_t)WINDOW.get() & 0xFFFFFFFF);
});
}
bool CToplevelMappingManager::good() const {
return resource->resource();
return m_resource->resource();
}
CToplevelMappingProtocol::CToplevelMappingProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {}
void CToplevelMappingProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeUnique<CToplevelMappingManager>(makeShared<CHyprlandToplevelMappingManagerV1>(client, ver, id))).get();
const auto RESOURCE = m_managers.emplace_back(makeUnique<CToplevelMappingManager>(makeShared<CHyprlandToplevelMappingManagerV1>(client, ver, id))).get();
if UNLIKELY (!RESOURCE->good()) {
LOGM(ERR, "Couldn't create a toplevel mapping manager");
wl_client_post_no_memory(client);
m_vManagers.pop_back();
m_managers.pop_back();
return;
}
}
void CToplevelMappingProtocol::onManagerResourceDestroy(CToplevelMappingManager* mgr) {
std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == mgr; });
std::erase_if(m_managers, [&](const auto& other) { return other.get() == mgr; });
}
void CToplevelMappingProtocol::destroyHandle(CHyprlandToplevelWindowMappingHandleV1* handle) {
std::erase_if(m_vHandles, [&](const auto& other) { return other->resource.get() == handle; });
std::erase_if(m_handles, [&](const auto& other) { return other->m_resource.get() == handle; });
}

View File

@@ -9,7 +9,7 @@ class CToplevelWindowMappingHandle {
CToplevelWindowMappingHandle(SP<CHyprlandToplevelWindowMappingHandleV1> resource_);
private:
SP<CHyprlandToplevelWindowMappingHandleV1> resource;
SP<CHyprlandToplevelWindowMappingHandleV1> m_resource;
friend class CToplevelMappingManager;
friend class CToplevelMappingProtocol;
@@ -22,7 +22,7 @@ class CToplevelMappingManager {
bool good() const;
private:
SP<CHyprlandToplevelMappingManagerV1> resource;
SP<CHyprlandToplevelMappingManagerV1> m_resource;
};
class CToplevelMappingProtocol : IWaylandProtocol {
@@ -35,8 +35,8 @@ class CToplevelMappingProtocol : IWaylandProtocol {
void onManagerResourceDestroy(CToplevelMappingManager* mgr);
void destroyHandle(CHyprlandToplevelWindowMappingHandleV1* handle);
std::vector<UP<CToplevelMappingManager>> m_vManagers;
std::vector<SP<CToplevelWindowMappingHandle>> m_vHandles;
std::vector<UP<CToplevelMappingManager>> m_managers;
std::vector<SP<CToplevelWindowMappingHandle>> m_handles;
friend class CToplevelMappingManager;
};