File indexing completed on 2024-09-08 13:20:32
0001 /* 0002 * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@blue-systems.com> 0003 * SPDX-FileCopyrightText: 2018 Drew DeVault <sir@cmpwn.com> 0004 * 0005 * SPDX-License-Identifier: LGPL-3.0-or-later 0006 */ 0007 0008 #include "interfaces/shell.h" 0009 #include "layershellqt_logging.h" 0010 #include "qwaylandlayershell_p.h" 0011 #include "qwaylandlayersurface_p.h" 0012 0013 #include <QtWaylandClient/private/qwaylandscreen_p.h> 0014 #include <QtWaylandClient/private/qwaylandsurface_p.h> 0015 #include <QtWaylandClient/private/qwaylandwindow_p.h> 0016 0017 namespace LayerShellQt 0018 { 0019 QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShell *shell, QtWaylandClient::QWaylandWindow *window) 0020 : QtWaylandClient::QWaylandShellSurface(window) 0021 , QtWayland::zwlr_layer_surface_v1() 0022 { 0023 LayerShellQt::Window *interface = Window::get(window->window()); 0024 Q_ASSERT(interface); 0025 0026 wl_output *output = nullptr; 0027 QScreen *screen = interface->desiredOutput(); 0028 if (screen) { 0029 auto waylandScreen = dynamic_cast<QtWaylandClient::QWaylandScreen *>(screen->handle()); 0030 // Qt will always assign a screen to a window, but if the compositor has no screens available a dummy QScreen object is created 0031 // this will not cast to a QWaylandScreen 0032 if (!waylandScreen) { 0033 qCWarning(LAYERSHELLQT) << "Creating a layer shell for placeholder screen. This will be positioned incorrectly"; 0034 } else { 0035 output = waylandScreen->output(); 0036 } 0037 } 0038 init(shell->get_layer_surface(window->waylandSurface()->object(), output, interface->layer(), interface->scope())); 0039 connect(interface, &Window::layerChanged, this, [this, interface]() { 0040 setLayer(interface->layer()); 0041 }); 0042 0043 set_anchor(interface->anchors()); 0044 connect(interface, &Window::anchorsChanged, this, [this, interface]() { 0045 set_anchor(interface->anchors()); 0046 }); 0047 setExclusiveZone(interface->exclusionZone()); 0048 connect(interface, &Window::exclusionZoneChanged, this, [this, interface]() { 0049 setExclusiveZone(interface->exclusionZone()); 0050 }); 0051 0052 setMargins(interface->margins()); 0053 connect(interface, &Window::marginsChanged, this, [this, interface]() { 0054 setMargins(interface->margins()); 0055 }); 0056 0057 setKeyboardInteractivity(interface->keyboardInteractivity()); 0058 connect(interface, &Window::keyboardInteractivityChanged, this, [this, interface]() { 0059 setKeyboardInteractivity(interface->keyboardInteractivity()); 0060 }); 0061 0062 QSize size = window->surfaceSize(); 0063 const Window::Anchors anchors = interface->anchors(); 0064 if ((anchors & Window::AnchorLeft) && (anchors & Window::AnchorRight)) { 0065 size.setWidth(0); 0066 } 0067 if ((anchors & Window::AnchorTop) && (anchors & Window::AnchorBottom)) { 0068 size.setHeight(0); 0069 } 0070 if (size.isValid() && size != QSize(0, 0)) { 0071 set_size(size.width(), size.height()); 0072 } 0073 } 0074 0075 QWaylandLayerSurface::~QWaylandLayerSurface() 0076 { 0077 destroy(); 0078 } 0079 0080 void QWaylandLayerSurface::zwlr_layer_surface_v1_closed() 0081 { 0082 window()->window()->close(); 0083 } 0084 0085 void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height) 0086 { 0087 ack_configure(serial); 0088 m_pendingSize = QSize(width, height); 0089 0090 if (!m_configured) { 0091 m_configured = true; 0092 window()->resizeFromApplyConfigure(m_pendingSize); 0093 window()->handleExpose(QRect(QPoint(), m_pendingSize)); 0094 } else { 0095 // Later configures are resizes, so we have to queue them up for a time when we 0096 // are not painting to the window. 0097 window()->applyConfigureWhenPossible(); 0098 } 0099 } 0100 0101 void QWaylandLayerSurface::applyConfigure() 0102 { 0103 window()->resizeFromApplyConfigure(m_pendingSize); 0104 } 0105 0106 void QWaylandLayerSurface::setAnchor(uint anchor) 0107 { 0108 set_anchor(anchor); 0109 } 0110 0111 void QWaylandLayerSurface::setExclusiveZone(int32_t zone) 0112 { 0113 set_exclusive_zone(zone); 0114 } 0115 0116 void QWaylandLayerSurface::setMargins(const QMargins &margins) 0117 { 0118 set_margin(margins.top(), margins.right(), margins.bottom(), margins.left()); 0119 } 0120 0121 void QWaylandLayerSurface::setKeyboardInteractivity(uint32_t interactivity) 0122 { 0123 set_keyboard_interactivity(interactivity); 0124 } 0125 0126 void QWaylandLayerSurface::setLayer(uint32_t layer) 0127 { 0128 if (zwlr_layer_surface_v1_get_version(object()) >= ZWLR_LAYER_SURFACE_V1_SET_LAYER_SINCE_VERSION) 0129 set_layer(layer); 0130 } 0131 0132 }