|
|
|
|
@ -380,12 +380,12 @@ void Compositor::addOutput(Output *output) |
|
|
|
|
cursorLayer->setParent(workspaceLayer); |
|
|
|
|
cursorLayer->setSuperlayer(workspaceLayer); |
|
|
|
|
|
|
|
|
|
auto updateCursorLayer = [this, output, cursorLayer]() { |
|
|
|
|
static bool valid; |
|
|
|
|
static const bool forceSoftwareCursor = qEnvironmentVariableIntValue("KWIN_FORCE_SW_CURSOR", &valid) == 1 && valid; |
|
|
|
|
static bool valid; |
|
|
|
|
static const bool forceSoftwareCursor = qEnvironmentVariableIntValue("KWIN_FORCE_SW_CURSOR", &valid) == 1 && valid; |
|
|
|
|
|
|
|
|
|
auto updateCursorLayer = [this, output, cursorLayer]() { |
|
|
|
|
const Cursor *cursor = Cursors::self()->currentCursor(); |
|
|
|
|
const QRectF layerRect = output->mapFromGlobal(cursor->geometry()); |
|
|
|
|
const QRectF outputLocalRect = output->mapFromGlobal(cursor->geometry()); |
|
|
|
|
const auto outputLayer = m_backend->cursorLayer(output); |
|
|
|
|
if (!cursor->isOnOutput(output)) { |
|
|
|
|
if (outputLayer && outputLayer->isEnabled()) { |
|
|
|
|
@ -393,23 +393,24 @@ void Compositor::addOutput(Output *output) |
|
|
|
|
output->updateCursorLayer(); |
|
|
|
|
} |
|
|
|
|
cursorLayer->setVisible(false); |
|
|
|
|
return; |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
const auto renderHardwareCursor = [&]() { |
|
|
|
|
if (!outputLayer || forceSoftwareCursor) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
const QMatrix4x4 monitorMatrix = Output::logicalToNativeMatrix(output->rect(), output->scale(), output->transform()); |
|
|
|
|
const QRectF nativeCursorRect = monitorMatrix.mapRect(layerRect); |
|
|
|
|
QRectF nativeCursorRect = monitorMatrix.mapRect(outputLocalRect); |
|
|
|
|
QSize bufferSize(std::ceil(nativeCursorRect.width()), std::ceil(nativeCursorRect.height())); |
|
|
|
|
if (const auto fixedSize = outputLayer->fixedSize()) { |
|
|
|
|
if (fixedSize->width() < bufferSize.width() || fixedSize->height() < bufferSize.height()) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
bufferSize = *fixedSize; |
|
|
|
|
nativeCursorRect = monitorMatrix.mapRect(QRectF(outputLocalRect.topLeft(), QSizeF(bufferSize) / output->scale())); |
|
|
|
|
} |
|
|
|
|
outputLayer->setPosition(nativeCursorRect.topLeft()); |
|
|
|
|
outputLayer->setHotspot(monitorMatrix.map(cursor->hotspot())); |
|
|
|
|
outputLayer->setHotspot(Output::logicalToNativeMatrix(QRectF(QPointF(), QSizeF(bufferSize) / output->scale()), output->scale(), output->transform()).map(cursor->hotspot())); |
|
|
|
|
outputLayer->setSize(bufferSize); |
|
|
|
|
if (auto beginInfo = outputLayer->beginFrame()) { |
|
|
|
|
const RenderTarget &renderTarget = beginInfo->renderTarget; |
|
|
|
|
@ -431,29 +432,36 @@ void Compositor::addOutput(Output *output) |
|
|
|
|
}; |
|
|
|
|
if (renderHardwareCursor()) { |
|
|
|
|
cursorLayer->setVisible(false); |
|
|
|
|
return true; |
|
|
|
|
} else { |
|
|
|
|
if (outputLayer && outputLayer->isEnabled()) { |
|
|
|
|
outputLayer->setEnabled(false); |
|
|
|
|
output->updateCursorLayer(); |
|
|
|
|
} |
|
|
|
|
cursorLayer->setVisible(cursor->isOnOutput(output)); |
|
|
|
|
cursorLayer->setGeometry(layerRect); |
|
|
|
|
cursorLayer->setGeometry(outputLocalRect); |
|
|
|
|
cursorLayer->addRepaintFull(); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
auto moveCursorLayer = [this, output, cursorLayer]() { |
|
|
|
|
auto moveCursorLayer = [this, output, cursorLayer, updateCursorLayer]() { |
|
|
|
|
const Cursor *cursor = Cursors::self()->currentCursor(); |
|
|
|
|
const QRectF layerRect = output->mapFromGlobal(cursor->geometry()); |
|
|
|
|
const QMatrix4x4 monitorMatrix = Output::logicalToNativeMatrix(output->rect(), output->scale(), output->transform()); |
|
|
|
|
const QRectF nativeCursorRect = monitorMatrix.mapRect(layerRect); |
|
|
|
|
const QRectF outputLocalRect = output->mapFromGlobal(cursor->geometry()); |
|
|
|
|
const auto outputLayer = m_backend->cursorLayer(output); |
|
|
|
|
bool hardwareCursor = false; |
|
|
|
|
if (outputLayer && outputLayer->isEnabled()) { |
|
|
|
|
outputLayer->setPosition(nativeCursorRect.topLeft()); |
|
|
|
|
hardwareCursor = output->updateCursorLayer(); |
|
|
|
|
if (outputLayer) { |
|
|
|
|
if (outputLayer->isEnabled()) { |
|
|
|
|
const QMatrix4x4 monitorMatrix = Output::logicalToNativeMatrix(output->rect(), output->scale(), output->transform()); |
|
|
|
|
const QRectF nativeCursorRect = monitorMatrix.mapRect(QRectF(outputLocalRect.topLeft(), outputLayer->size() / output->scale())); |
|
|
|
|
outputLayer->setPosition(nativeCursorRect.topLeft()); |
|
|
|
|
hardwareCursor = output->updateCursorLayer(); |
|
|
|
|
} else if (!cursorLayer->isVisible() && !forceSoftwareCursor) { |
|
|
|
|
// this is for the case that the cursor wasn't visible because it was on a different output before
|
|
|
|
|
hardwareCursor = updateCursorLayer(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
cursorLayer->setVisible(cursor->isOnOutput(output) && !hardwareCursor); |
|
|
|
|
cursorLayer->setGeometry(layerRect); |
|
|
|
|
cursorLayer->setGeometry(outputLocalRect); |
|
|
|
|
cursorLayer->addRepaintFull(); |
|
|
|
|
}; |
|
|
|
|
updateCursorLayer(); |
|
|
|
|
|