commit ea3e4b3139cee70a9a774b08c306eecd0c860d50 Author: Aleix Pol Date: Thu Apr 1 02:28:01 2021 +0200 Initial commit diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..11ff049 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,58 @@ +cmake_minimum_required(VERSION 3.16) + +project(layershellqt) +set(PROJECT_VERSION "5.21.80") +set(PROJECT_VERSION_MAJOR 5) + +set(QT_MIN_VERSION "5.15.0") +set(KF5_MIN_VERSION "5.78") + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS WaylandClient Qml) +find_package(Qt5XkbCommonSupport REQUIRED PRIVATE) +find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${ECM_MODULE_PATH} ) + +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDECompilerSettings NO_POLICY_SCOPE) +include(ECMSetupVersion) +include(ECMGenerateHeaders) +include(CheckIncludeFiles) +include(CMakePackageConfigHelpers) +include(FeatureSummary) +include(GenerateExportHeader) +include(KDEClangFormat) + +find_package(WaylandScanner) +find_package(QtWaylandScanner) +find_package(Wayland 1.3 COMPONENTS Client Server) +find_package(WaylandProtocols) + +set_package_properties(Wayland PROPERTIES + TYPE REQUIRED) +# adjusting CMAKE_C_FLAGS to get wayland protocols to compile +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu90") + +ecm_setup_version(${PROJECT_VERSION} VARIABLE_PREFIX LAYERSHELL_QT + VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/layershellqt_version.h" + PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/LayerShellQtConfigVersion.cmake" + SOVERSION 5) + +include(ECMQtDeclareLoggingCategory) +add_subdirectory(src) +add_subdirectory(tests) + +ecm_qt_declare_logging_category(ksld_SRCS + HEADER + layershellqt_logging.h + IDENTIFIER + LAYERSHELL_QT + CATEGORY_NAME + layershellqt + DEFAULT_SEVERITY + Critical +) +feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..021e2ee --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,23 @@ +remove_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS) + +ecm_add_qtwayland_client_protocol(LAYER_SHELL_SOURCES PROTOCOL ${WaylandProtocols_DATADIR}/stable/xdg-shell/xdg-shell.xml BASENAME xdg-shell) +ecm_add_qtwayland_client_protocol(LAYER_SHELL_SOURCES PROTOCOL wlr-layer-shell-unstable-v1.xml BASENAME wlr-layer-shell-unstable-v1) + +add_library(layer-shell SHARED qwaylandlayersurface.cpp qwaylandlayershellintegration.cpp qwaylandlayershell.cpp qwaylandlayershellintegrationplugin.cpp ${LAYER_SHELL_SOURCES}) +target_link_libraries(layer-shell Qt5::WaylandClient Wayland::Client Qt5::XkbCommonSupportPrivate Qt::WaylandClientPrivate) +target_include_directories(layer-shell PRIVATE "$/LayerShellQt") + +add_library(LayerShellQtInterface SHARED interfaces/window.cpp interfaces/shell.cpp) +target_link_libraries(LayerShellQtInterface PRIVATE layer-shell PUBLIC Qt5::Gui) +target_include_directories(LayerShellQtInterface PUBLIC "$/LayerShellQt" + INTERFACE "$" +) + +generate_export_header(LayerShellQtInterface + BASE_NAME LayerShellQtInterface + EXPORT_MACRO_NAME LAYERSHELLQT_EXPORT + EXPORT_FILE_NAME LayerShellQt/layershellqt_export.h +) + +install(TARGETS layer-shell + LIBRARY DESTINATION ${QT_PLUGIN_INSTALL_DIR}/wayland-shell-integration) diff --git a/src/interfaces/shell.cpp b/src/interfaces/shell.cpp new file mode 100644 index 0000000..19d8269 --- /dev/null +++ b/src/interfaces/shell.cpp @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#include "shell.h" +#include +#include + +using namespace LayerShellQt; + +void Shell::useLayerShell() +{ + qputenv("QT_WAYLAND_SHELL_INTEGRATION", "layer-shell"); +} diff --git a/src/interfaces/shell.h b/src/interfaces/shell.h new file mode 100644 index 0000000..5160d78 --- /dev/null +++ b/src/interfaces/shell.h @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#ifndef LAYERSHELLQTSHELL_H +#define LAYERSHELLQTSHELL_H + +#include "layershellqt_export.h" + +namespace LayerShellQt +{ + +/** + * Sets the right environment so the shells created from now on use wlr-layer-shell. + */ +class LAYERSHELLQT_EXPORT Shell { +public: + static void useLayerShell(); +}; + +} + +#endif diff --git a/src/interfaces/window.cpp b/src/interfaces/window.cpp new file mode 100644 index 0000000..bae4e6e --- /dev/null +++ b/src/interfaces/window.cpp @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#include "window.h" +#include +#include +#include +#include "../qwaylandlayersurface_p.h" + +using namespace LayerShellQt; + +class LayerShellQt::WindowPrivate +{ +public: + WindowPrivate(QWaylandLayerSurface *surface) + : surface(surface) + { + } + + QWaylandLayerSurface *const surface; +}; + +Window::~Window() = default; + +void Window::setAnchor(Anchor anchor) +{ + d->surface->setAnchor(anchor); +} + +void Window::setExclusiveZone(int32_t zone) +{ + d->surface->setExclusiveZone(zone); +} + +void Window::setMargins(const QMargins &margins) +{ + d->surface->setMargins(margins); +} + +void Window::setKeyboardInteractivity(bool enabled) +{ + d->surface->setKeyboardInteractivity(enabled); +} + +Window::Window(WindowPrivate *d) + : d(d) +{} + +Window *Window::get(QWindow *window) +{ + auto ww = dynamic_cast(window->handle()); + if (!ww) { + qDebug() << "window not a wayland window" << window; + return nullptr; + } + QWaylandLayerSurface* s = qobject_cast(ww->shellSurface()); + if (!s) { + qDebug() << "window not using wlr-layer-shell" << window << ww->shellSurface(); + return nullptr; + } + + return new Window(new WindowPrivate(s)); +} diff --git a/src/interfaces/window.h b/src/interfaces/window.h new file mode 100644 index 0000000..78cc9ce --- /dev/null +++ b/src/interfaces/window.h @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + * SPDX-FileCopyrightText: 2018 Drew DeVault + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#ifndef LAYERSHELLQTWINDOW_H +#define LAYERSHELLQTWINDOW_H + +#include +#include + +#include "layershellqt_export.h" + +namespace LayerShellQt +{ +class WindowPrivate; + +class LAYERSHELLQT_EXPORT Window : public QObject +{ + Q_OBJECT +public: + ~Window() override; + + enum Anchor { + AnchorTop = 1, // the top edge of the anchor rectangle + AnchorBottom = 2, // the bottom edge of the anchor rectangle + AnchorLeft = 4, // the left edge of the anchor rectangle + AnchorRight = 8, // the right edge of the anchor rectangle + }; + Q_ENUM(Anchor); + + void setAnchor(Anchor anchor); + void setExclusiveZone(int32_t zone); + void setMargins(const QMargins &margins); + void setKeyboardInteractivity(bool enabled); + + static Window *get(QWindow *window); + +private: + Window(WindowPrivate *d); + QScopedPointer d; +}; + +} + +#endif diff --git a/src/layer-shell.json b/src/layer-shell.json new file mode 100644 index 0000000..c96e97c --- /dev/null +++ b/src/layer-shell.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "layer-shell" ] +} diff --git a/src/qwaylandlayershell.cpp b/src/qwaylandlayershell.cpp new file mode 100644 index 0000000..b64638f --- /dev/null +++ b/src/qwaylandlayershell.cpp @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + * SPDX-FileCopyrightText: 2018 Drew DeVault + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#include "qwaylandlayershell_p.h" +#include "qwaylandlayersurface_p.h" + +#include + +namespace LayerShellQt { + +QWaylandLayerShell::QWaylandLayerShell(struct QtWayland::zwlr_layer_shell_v1 *shell) + : QtWayland::zwlr_layer_shell_v1(shell->object()) +{ +} + +QWaylandLayerShell::~QWaylandLayerShell() +{ + zwlr_layer_shell_v1_destroy(object()); +} + +QWaylandLayerSurface *QWaylandLayerShell::createLayerSurface( + QtWaylandClient::QWaylandWindow *window) +{ + return new QWaylandLayerSurface(this, window); +} + +} diff --git a/src/qwaylandlayershell_p.h b/src/qwaylandlayershell_p.h new file mode 100644 index 0000000..ddef3a8 --- /dev/null +++ b/src/qwaylandlayershell_p.h @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + * SPDX-FileCopyrightText: 2018 Drew DeVault + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#ifndef _LAYERSHELL_H +#define _LAYERSHELL_H + +#include + +#include +#include + +#include "qwaylandlayersurface_p.h" + +namespace LayerShellQt { + +class QWaylandLayerShell : public QtWayland::zwlr_layer_shell_v1 +{ +public: + QWaylandLayerShell(struct QtWayland::zwlr_layer_shell_v1 *shell); + virtual ~QWaylandLayerShell(); + + QWaylandLayerSurface *createLayerSurface( + QtWaylandClient::QWaylandWindow *window); + // TODO: Popups +}; + +} + +#endif diff --git a/src/qwaylandlayershellintegration.cpp b/src/qwaylandlayershellintegration.cpp new file mode 100644 index 0000000..83a2dcb --- /dev/null +++ b/src/qwaylandlayershellintegration.cpp @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + * SPDX-FileCopyrightText: 2018 Drew DeVault + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#include "qwaylandlayershellintegration_p.h" +#include "qwaylandlayershell_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +namespace LayerShellQt { + +QWaylandLayerShellIntegration::QWaylandLayerShellIntegration() : + m_layerShell(Q_NULLPTR) +{ +} + +bool QWaylandLayerShellIntegration::initialize(QtWaylandClient::QWaylandDisplay *display) +{ + QWaylandShellIntegration::initialize(display); + display->addRegistryListener(registryLayer, this); + return m_layerShell != nullptr; +} + +QtWaylandClient::QWaylandShellSurface *QWaylandLayerShellIntegration:: + createShellSurface(QtWaylandClient::QWaylandWindow *window) +{ + return m_layerShell->createLayerSurface(window); +} + +void QWaylandLayerShellIntegration::registryLayer(void *data, + struct wl_registry *registry, uint32_t id, + const QString &interface, uint32_t version) +{ + QWaylandLayerShellIntegration *shell = + static_cast(data); + + if (interface == QStringLiteral("zwlr_layer_shell_v1")) + shell->m_layerShell = new QWaylandLayerShell( + new QtWayland::zwlr_layer_shell_v1(registry, id, version)); +} + +} + +QT_END_NAMESPACE + +//#include "qwaylandlayershellintegration.moc" diff --git a/src/qwaylandlayershellintegration_p.h b/src/qwaylandlayershellintegration_p.h new file mode 100644 index 0000000..69daf13 --- /dev/null +++ b/src/qwaylandlayershellintegration_p.h @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + * SPDX-FileCopyrightText: 2018 Drew DeVault + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#ifndef _LAYERSHELLINTEGRATION_P_H +#define _LAYERSHELLINTEGRATION_P_H + +#include + +#include + +namespace LayerShellQt { + +class QWaylandLayerShell; + +class QWaylandLayerShellIntegration : public QtWaylandClient::QWaylandShellIntegration +{ +public: + QWaylandLayerShellIntegration(); + + bool initialize(QtWaylandClient::QWaylandDisplay *display) override; + QtWaylandClient::QWaylandShellSurface *createShellSurface( + QtWaylandClient::QWaylandWindow *window) override; + +private: + static void registryLayer(void *data, struct wl_registry *registry, + uint32_t id, const QString &interface, uint32_t version); + + QWaylandLayerShell *m_layerShell; +}; + +} + +#endif diff --git a/src/qwaylandlayershellintegrationplugin.cpp b/src/qwaylandlayershellintegrationplugin.cpp new file mode 100644 index 0000000..b3152a2 --- /dev/null +++ b/src/qwaylandlayershellintegrationplugin.cpp @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + * SPDX-FileCopyrightText: 2018 Drew DeVault + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#include +#include "qwaylandlayershellintegration_p.h" + +using namespace LayerShellQt; + +class QWaylandLayerShellIntegrationPlugin : + public QtWaylandClient::QWaylandShellIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA( + IID QWaylandShellIntegrationFactoryInterface_iid + FILE "layer-shell.json") + +public: + QWaylandLayerShellIntegrationPlugin() {} + + QtWaylandClient::QWaylandShellIntegration *create( + const QString &key, const QStringList ¶mList) override { + Q_UNUSED(key); + Q_UNUSED(paramList); + return new QWaylandLayerShellIntegration(); + } +}; + +// Q_IMPORT_PLUGIN(QWaylandLayerShellIntegrationPlugin); + +#include "qwaylandlayershellintegrationplugin.moc" diff --git a/src/qwaylandlayersurface.cpp b/src/qwaylandlayersurface.cpp new file mode 100644 index 0000000..d544a79 --- /dev/null +++ b/src/qwaylandlayersurface.cpp @@ -0,0 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + * SPDX-FileCopyrightText: 2018 Drew DeVault + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#include "qwaylandlayershell_p.h" +#include "qwaylandlayersurface_p.h" + +#include +#include +#include +#include + +namespace LayerShellQt { + +QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShell *shell, QtWaylandClient::QWaylandWindow *window) + : QtWaylandClient::QWaylandShellSurface(window) + , QtWayland::zwlr_layer_surface_v1( + // TODO: Specify namespace + shell->get_layer_surface(window->waylandSurface()->object(), + window->waylandScreen()->output(), + QtWayland::zwlr_layer_shell_v1::layer_top, + QStringLiteral("qt"))) +{ + set_anchor(anchor_top | anchor_bottom | anchor_left | anchor_right); +} + +QWaylandLayerSurface::~QWaylandLayerSurface() +{ + destroy(); +} + +void QWaylandLayerSurface::zwlr_layer_surface_v1_closed() +{ + window()->window()->close(); +} + +void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, + uint32_t width, uint32_t height) +{ + ack_configure(serial); + m_pendingSize = QSize(width, height); + + if (!m_configured) { + m_configured = true; + window()->resizeFromApplyConfigure(m_pendingSize); + window()->handleExpose(QRect(QPoint(), m_pendingSize)); + } else { + // Later configures are resizes, so we have to queue them up for a time when we + // are not painting to the window. + window()->applyConfigureWhenPossible(); + } +} + +void QWaylandLayerSurface::applyConfigure() +{ + window()->resizeFromApplyConfigure(m_pendingSize); +} + +void QWaylandLayerSurface::setAnchor(uint anchor) +{ + set_anchor(anchor); +} + +void QWaylandLayerSurface::setExclusiveZone(int32_t zone) +{ + set_exclusive_zone(zone); +} + +void QWaylandLayerSurface::setMargins(const QMargins &margins) +{ + set_margin(margins.top(), margins.right(), margins.bottom(), margins.left()); +} + +void QWaylandLayerSurface::setKeyboardInteractivity(bool enabled) +{ + set_keyboard_interactivity(enabled); +} + +} diff --git a/src/qwaylandlayersurface_p.h b/src/qwaylandlayersurface_p.h new file mode 100644 index 0000000..3115267 --- /dev/null +++ b/src/qwaylandlayersurface_p.h @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + * SPDX-FileCopyrightText: 2018 Drew DeVault + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#ifndef _LAYERSURFACE_H +#define _LAYERSURFACE_H + +#include + +#include +#include +#include "layershellqt_export.h" + +namespace LayerShellQt { + +class QWaylandLayerShell; + +class LAYERSHELLQT_EXPORT QWaylandLayerSurface : public QtWaylandClient::QWaylandShellSurface, + public QtWayland::zwlr_layer_surface_v1 +{ + Q_OBJECT +public: + QWaylandLayerSurface(QWaylandLayerShell *shell, + QtWaylandClient::QWaylandWindow *window); + virtual ~QWaylandLayerSurface(); + + bool isExposed() const override { + return m_configured; + } + + void setAnchor(uint32_t anchor); + void setExclusiveZone(int32_t zone); + void setMargins(const QMargins &margins); + void setKeyboardInteractivity(bool enabled); + + void applyConfigure() override; + +private: + void zwlr_layer_surface_v1_configure(uint32_t serial, + uint32_t width, uint32_t height) override; + void zwlr_layer_surface_v1_closed() override; + + QSize m_pendingSize; + bool m_configured = false; +}; + +} + +#endif diff --git a/src/wlr-layer-shell-unstable-v1.xml b/src/wlr-layer-shell-unstable-v1.xml new file mode 100644 index 0000000..fcfdd98 --- /dev/null +++ b/src/wlr-layer-shell-unstable-v1.xml @@ -0,0 +1,286 @@ + + + + Copyright © 2017 Drew DeVault + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + + + + + Clients can use this interface to assign the surface_layer role to + wl_surfaces. Such surfaces are assigned to a "layer" of the output and + rendered with a defined z-depth respective to each other. They may also be + anchored to the edges and corners of a screen and specify input handling + semantics. This interface should be suitable for the implementation of + many desktop shell components, and a broad number of other applications + that interact with the desktop. + + + + + Create a layer surface for an existing surface. This assigns the role of + layer_surface, or raises a protocol error if another role is already + assigned. + + Creating a layer surface from a wl_surface which has a buffer attached + or committed is a client error, and any attempts by a client to attach + or manipulate a buffer prior to the first layer_surface.configure call + must also be treated as errors. + + You may pass NULL for output to allow the compositor to decide which + output to use. Generally this will be the one that the user most + recently interacted with. + + Clients can specify a namespace that defines the purpose of the layer + surface. + + + + + + + + + + + + + + + + + + These values indicate which layers a surface can be rendered in. They + are ordered by z depth, bottom-most first. Traditional shell surfaces + will typically be rendered between the bottom and top layers. + Fullscreen shell surfaces are typically rendered at the top layer. + Multiple surfaces can share a single layer, and ordering within a + single layer is undefined. + + + + + + + + + + + + An interface that may be implemented by a wl_surface, for surfaces that + are designed to be rendered as a layer of a stacked desktop-like + environment. + + Layer surface state (size, anchor, exclusive zone, margin, interactivity) + is double-buffered, and will be applied at the time wl_surface.commit of + the corresponding wl_surface is called. + + + + + Sets the size of the surface in surface-local coordinates. The + compositor will display the surface centered with respect to its + anchors. + + If you pass 0 for either value, the compositor will assign it and + inform you of the assignment in the configure event. You must set your + anchor to opposite edges in the dimensions you omit; not doing so is a + protocol error. Both values are 0 by default. + + Size is double-buffered, see wl_surface.commit. + + + + + + + + Requests that the compositor anchor the surface to the specified edges + and corners. If two orthoginal edges are specified (e.g. 'top' and + 'left'), then the anchor point will be the intersection of the edges + (e.g. the top left corner of the output); otherwise the anchor point + will be centered on that edge, or in the center if none is specified. + + Anchor is double-buffered, see wl_surface.commit. + + + + + + + Requests that the compositor avoids occluding an area of the surface + with other surfaces. The compositor's use of this information is + implementation-dependent - do not assume that this region will not + actually be occluded. + + A positive value is only meaningful if the surface is anchored to an + edge, rather than a corner. The zone is the number of surface-local + coordinates from the edge that are considered exclusive. + + Surfaces that do not wish to have an exclusive zone may instead specify + how they should interact with surfaces that do. If set to zero, the + surface indicates that it would like to be moved to avoid occluding + surfaces with a positive excluzive zone. If set to -1, the surface + indicates that it would not like to be moved to accomodate for other + surfaces, and the compositor should extend it all the way to the edges + it is anchored to. + + For example, a panel might set its exclusive zone to 10, so that + maximized shell surfaces are not shown on top of it. A notification + might set its exclusive zone to 0, so that it is moved to avoid + occluding the panel, but shell surfaces are shown underneath it. A + wallpaper or lock screen might set their exclusive zone to -1, so that + they stretch below or over the panel. + + The default value is 0. + + Exclusive zone is double-buffered, see wl_surface.commit. + + + + + + + Requests that the surface be placed some distance away from the anchor + point on the output, in surface-local coordinates. Setting this value + for edges you are not anchored to has no effect. + + The exclusive zone includes the margin. + + Margin is double-buffered, see wl_surface.commit. + + + + + + + + + + Set to 1 to request that the seat send keyboard events to this layer + surface. For layers below the shell surface layer, the seat will use + normal focus semantics. For layers above the shell surface layers, the + seat will always give exclusive keyboard focus to the top-most layer + which has keyboard interactivity set to true. + + Layer surfaces receive pointer, touch, and tablet events normally. If + you do not want to receive them, set the input region on your surface + to an empty region. + + Events is double-buffered, see wl_surface.commit. + + + + + + + This assigns an xdg_popup's parent to this layer_surface. This popup + should have been created via xdg_surface::get_popup with the parent set + to NULL, and this request must be invoked before committing the popup's + initial state. + + See the documentation of xdg_popup for more details about what an + xdg_popup is and how it is used. + + + + + + + When a configure event is received, if a client commits the + surface in response to the configure event, then the client + must make an ack_configure request sometime before the commit + request, passing along the serial of the configure event. + + If the client receives multiple configure events before it + can respond to one, it only has to ack the last configure event. + + A client is not required to commit immediately after sending + an ack_configure request - it may even ack_configure several times + before its next surface commit. + + A client may send multiple ack_configure requests before committing, but + only the last request sent before a commit indicates which configure + event the client really is responding to. + + + + + + + This request destroys the layer surface. + + + + + + The configure event asks the client to resize its surface. + + Clients should arrange their surface for the new states, and then send + an ack_configure request with the serial sent in this configure event at + some point before committing the new surface. + + The client is free to dismiss all but the last configure event it + received. + + The width and height arguments specify the size of the window in + surface-local coordinates. + + The size is a hint, in the sense that the client is free to ignore it if + it doesn't resize, pick a smaller size (to satisfy aspect ratio or + resize in steps of NxM pixels). If the client picks a smaller size and + is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the + surface will be centered on this axis. + + If the width or height arguments are zero, it means the client should + decide its own window dimension. + + + + + + + + + The closed event is sent by the compositor when the surface will no + longer be shown. The output may have been destroyed or the user may + have asked for it to be removed. Further changes to the surface will be + ignored. The client should destroy the resource after receiving this + event, and create a new surface if they so choose. + + + + + + + + + + + + + + + + + diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..39b260b --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(layershellqt-test main.cpp) +target_link_libraries(layershellqt-test PRIVATE LayerShellQtInterface Qt5::Qml) diff --git a/tests/main.cpp b/tests/main.cpp new file mode 100644 index 0000000..9557335 --- /dev/null +++ b/tests/main.cpp @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + LayerShellQt::Shell::useLayerShell(); + + QGuiApplication app(argc, argv); + QQmlApplicationEngine engine; + engine.loadData("import QtQuick.Controls 2.10\n" + "import QtQuick 2.10\n" + "\n" + "ApplicationWindow {" + " width: 100; height: 100\n" + " visible: true\n" + " Rectangle { color: 'red'; anchors.fill: parent }" + "}" + + , QStringLiteral("bananaland:/potato.qml")); + + QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [] (QObject *object) { + auto layerWindow = LayerShellQt::Window::get(qobject_cast(object)); + Q_ASSERT(layerWindow); + layerWindow->setMargins({50, 50, 50, 50}); + }); + + return app.exec(); +}