Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 143 additions & 44 deletions frame/layershell/qwaylandlayershellsurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,63 +24,35 @@
, QtWayland::zwlr_layer_surface_v1()
, m_dlayerShellWindow(DLayerShellWindow::get(window->window()))
{

wl_output *output = nullptr;
if (m_dlayerShellWindow->screenConfiguration() == DLayerShellWindow::ScreenFromQWindow) {
auto waylandScreen = dynamic_cast<QtWaylandClient::QWaylandScreen*>(window->window()->screen()->handle());
connect(window->window(), &QWindow::screenChanged, this, [window](){
window->reset();
// make sure window has been cleaned completed
QMetaObject::invokeMethod(
window,
[window]() {
window->reinit();
},
Qt::QueuedConnection);
});
if (!waylandScreen) {
output = currentOutput();
connect(window->window(), &QWindow::screenChanged, this, &QWaylandLayerShellSurface::scheduleRecreate);
if (!output) {
qCWarning(layershellsurface) << "failed to get screen for wayland";
} else {
output = waylandScreen->output();
}
}

init(shell->get_layer_surface(window->waylandSurface()->object(), output, m_dlayerShellWindow->layer(), m_dlayerShellWindow->scope()));
m_output = output;

set_layer(m_dlayerShellWindow->layer());
connect(m_dlayerShellWindow, &DLayerShellWindow::layerChanged, this, [this, window](){
set_layer(m_dlayerShellWindow->layer());
window->waylandSurface()->commit();
});
applyLayer();
connect(m_dlayerShellWindow, &DLayerShellWindow::layerChanged, this, &QWaylandLayerShellSurface::applyLayer);

set_anchor(m_dlayerShellWindow->anchors());
connect(m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, this,[this, window](){
trySetAnchorsAndSize();
});
connect(m_dlayerShellWindow, &DLayerShellWindow::anchorsChanged, this, &QWaylandLayerShellSurface::trySetAnchorsAndSize);

set_exclusive_zone(m_dlayerShellWindow->exclusionZone());
connect(m_dlayerShellWindow, &DLayerShellWindow::exclusionZoneChanged, this,[this, window](){
set_exclusive_zone(m_dlayerShellWindow->exclusionZone());
window->waylandSurface()->commit();
});
applyExclusiveZone();
connect(m_dlayerShellWindow, &DLayerShellWindow::exclusionZoneChanged, this, &QWaylandLayerShellSurface::applyExclusiveZone);

set_margin(m_dlayerShellWindow->topMargin(), m_dlayerShellWindow->rightMargin(), m_dlayerShellWindow->bottomMargin(), m_dlayerShellWindow->leftMargin());
connect(m_dlayerShellWindow, &DLayerShellWindow::marginsChanged, this, [this](){
set_margin(m_dlayerShellWindow->topMargin(), m_dlayerShellWindow->rightMargin(), m_dlayerShellWindow->bottomMargin(), m_dlayerShellWindow->leftMargin());
});
applyMargins();
connect(m_dlayerShellWindow, &DLayerShellWindow::marginsChanged, this, &QWaylandLayerShellSurface::applyMargins);

set_keyboard_interactivity(m_dlayerShellWindow->keyboardInteractivity());
connect(m_dlayerShellWindow, &DLayerShellWindow::keyboardInteractivityChanged, this, [this, window](){
set_keyboard_interactivity(m_dlayerShellWindow->keyboardInteractivity());
window->waylandSurface()->commit();
});
applyKeyboardInteractivity();
connect(m_dlayerShellWindow, &DLayerShellWindow::keyboardInteractivityChanged, this, &QWaylandLayerShellSurface::applyKeyboardInteractivity);

auto applyInputRegion = [this, window]() {
window->window()->setMask(m_dlayerShellWindow->inputRegion());
window->waylandSurface()->commit();
};

connect(m_dlayerShellWindow, &DLayerShellWindow::inputRegionChanged, this, applyInputRegion);
applyInputRegion();
connect(m_dlayerShellWindow, &DLayerShellWindow::inputRegionChanged, this, &QWaylandLayerShellSurface::applyInputRegion);

calcAndSetRequestSize(window->surfaceSize());

Expand All @@ -101,6 +73,33 @@
}
}

QtWaylandClient::QWaylandWindow *QWaylandLayerShellSurface::waylandWindow()
{
return window();
}

QWindow *QWaylandLayerShellSurface::windowHandle()
{
auto currentWindow = waylandWindow();
return currentWindow ? currentWindow->window() : nullptr;
}

QtWaylandClient::QWaylandScreen *QWaylandLayerShellSurface::waylandScreen()
{
auto currentWindowHandle = windowHandle();
if (!currentWindowHandle || !currentWindowHandle->screen()) {
return nullptr;
}

return dynamic_cast<QtWaylandClient::QWaylandScreen *>(currentWindowHandle->screen()->handle());
}

wl_output *QWaylandLayerShellSurface::currentOutput()
{
auto currentWaylandScreen = waylandScreen();
return currentWaylandScreen ? currentWaylandScreen->output() : nullptr;
}

void QWaylandLayerShellSurface::calcAndSetRequestSize(QSize requestSize)
{
auto anchors = m_dlayerShellWindow->anchors();
Expand Down Expand Up @@ -128,11 +127,46 @@
if (!anchorsSizeConflict()) {
set_anchor(m_dlayerShellWindow->anchors());
set_size(m_requestSize.width(), m_requestSize.height());
window()->waylandSurface()->commit();
scheduleCommit();
}
}

void QWaylandLayerShellSurface::applyLayer()
{
set_layer(m_dlayerShellWindow->layer());
scheduleCommit();
}

void QWaylandLayerShellSurface::applyExclusiveZone()
{
set_exclusive_zone(m_dlayerShellWindow->exclusionZone());
scheduleCommit();
}

void QWaylandLayerShellSurface::applyMargins()
{
set_margin(m_dlayerShellWindow->topMargin(), m_dlayerShellWindow->rightMargin(), m_dlayerShellWindow->bottomMargin(), m_dlayerShellWindow->leftMargin());
scheduleCommit();
}

void QWaylandLayerShellSurface::applyKeyboardInteractivity()
{
set_keyboard_interactivity(m_dlayerShellWindow->keyboardInteractivity());
scheduleCommit();
}

void QWaylandLayerShellSurface::applyInputRegion()
{
auto currentWindowHandle = windowHandle();
if (!currentWindowHandle) {
return;
}

currentWindowHandle->setMask(m_dlayerShellWindow->inputRegion());
scheduleCommit();
}

void QWaylandLayerShellSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height)

Check warning on line 169 in frame/layershell/qwaylandlayershellsurface.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'zwlr_layer_surface_v1_configure' is never used.
{
ack_configure(serial);
m_pendingSize = QSize(width, height);
Expand Down Expand Up @@ -164,6 +198,71 @@
trySetAnchorsAndSize();
}

void QWaylandLayerShellSurface::commitWindowState()
{
auto currentWaylandWindow = waylandWindow();
if (!currentWaylandWindow || !currentWaylandWindow->waylandSurface()) {
return;
}

currentWaylandWindow->waylandSurface()->commit();
}

void QWaylandLayerShellSurface::flushCommit()
{
m_commitScheduled = false;
commitWindowState();
}

void QWaylandLayerShellSurface::scheduleCommit()
{
if (m_commitScheduled) {
return;
}

m_commitScheduled = true;
QMetaObject::invokeMethod(this, &QWaylandLayerShellSurface::flushCommit, Qt::QueuedConnection);
}

void QWaylandLayerShellSurface::recreateWindow()
{
auto currentWaylandWindow = waylandWindow();
if (!currentWaylandWindow) {
return;
}

currentWaylandWindow->reset();
QMetaObject::invokeMethod(currentWaylandWindow, &QtWaylandClient::QWaylandWindow::reinit, Qt::QueuedConnection);
}

void QWaylandLayerShellSurface::flushRecreate()
{
m_recreateScheduled = false;
recreateWindow();
}

void QWaylandLayerShellSurface::scheduleRecreate()
{
auto currentWindowHandle = windowHandle();

Check warning on line 246 in frame/layershell/qwaylandlayershellsurface.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Variable 'currentWindowHandle' can be declared as pointer to const
if (!currentWindowHandle) {
return;
}

const auto output = currentOutput();
if (!output) {
qCWarning(layershellsurface) << "failed to get screen for wayland";
return;
}

if (output == m_output || m_recreateScheduled) {
return;
}

m_output = output;
m_recreateScheduled = true;
QMetaObject::invokeMethod(this, &QWaylandLayerShellSurface::flushRecreate, Qt::QueuedConnection);
}

void QWaylandLayerShellSurface::attachPopup(QtWaylandClient::QWaylandShellSurface *popup)
{
std::any anyRole = popup->surfaceRole();
Expand Down
20 changes: 19 additions & 1 deletion frame/layershell/qwaylandlayershellsurface_p.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand Down Expand Up @@ -33,14 +33,32 @@ class QWaylandLayerShellSurface : public QtWaylandClient::QWaylandShellSurface,
void zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height) override;
void zwlr_layer_surface_v1_closed() override;

QtWaylandClient::QWaylandWindow *waylandWindow();
QWindow *windowHandle();
QtWaylandClient::QWaylandScreen *waylandScreen();
wl_output *currentOutput();
void calcAndSetRequestSize(QSize requestSize);
bool anchorsSizeConflict() const;
void trySetAnchorsAndSize();
void applyLayer();
void applyExclusiveZone();
void applyMargins();
void applyKeyboardInteractivity();
void applyInputRegion();
void commitWindowState();
void flushCommit();
void scheduleCommit();
void recreateWindow();
void flushRecreate();
void scheduleRecreate();

DLayerShellWindow* m_dlayerShellWindow;
QSize m_pendingSize;
QSize m_requestSize;
wl_output *m_output = nullptr;
bool m_configured = false;
bool m_commitScheduled = false;
bool m_recreateScheduled = false;
};

DS_END_NAMESPACE
Loading