Compare commits

..

1 Commits

Author SHA1 Message Date
7aa5a16038 Add API to choose an initial state of the window 2021-04-14 17:52:31 +02:00
19 changed files with 150 additions and 405 deletions

29
.gitignore vendored
View File

@ -1,29 +0,0 @@
# SPDX-License-Identifier: CC0-1.0
# SPDX-FileCopyrightText: none
# Ignore the following files
.vscode
*~
*.[oa]
*.diff
*.kate-swp
*.kdev4
.kdev_include_paths
*.kdevelop.pcs
*.moc
*.moc.cpp
*.orig
*.user
.*.swp
.swp.*
Doxyfile
Makefile
avail
random_seed
/build*/
CMakeLists.txt.user*
.clang-format
/compile_commands.json
.clangd
.idea
/cmake-build*
.cache

View File

@ -1,7 +0,0 @@
# SPDX-FileCopyrightText: None
# SPDX-License-Identifier: CC0-1.0
include:
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux-qt6.yml

View File

@ -1,7 +0,0 @@
# SPDX-FileCopyrightText: None
# SPDX-License-Identifier: CC0-1.0
Dependencies:
- 'on': ['@all']
'require':
'frameworks/extra-cmake-modules': '@latest'

View File

@ -4,18 +4,17 @@
cmake_minimum_required(VERSION 3.16)
project(layershellqt)
set(PROJECT_VERSION "5.25.5")
set(PROJECT_VERSION "5.21.80")
set(PROJECT_VERSION_MAJOR 5)
set(CMAKE_C_STANDARD 99)
set(QT_MIN_VERSION "5.15.2")
set(KF5_MIN_VERSION "5.94")
set(KDE_COMPILERSETTINGS_LEVEL "5.82")
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})
@ -30,17 +29,10 @@ include(GenerateExportHeader)
include(KDEClangFormat)
include(ECMQtDeclareLoggingCategory)
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS WaylandClient Qml)
if (QT_MAJOR_VERSION EQUAL "5")
find_package(Qt5XkbCommonSupport REQUIRED PRIVATE)
find_package(QtWaylandScanner REQUIRED)
endif()
find_package(WaylandScanner REQUIRED)
find_package(WaylandScanner)
find_package(QtWaylandScanner)
find_package(Wayland 1.3 COMPONENTS Client Server)
find_package(WaylandProtocols REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(XKBCOMMON xkbcommon REQUIRED IMPORTED_TARGET)
find_package(WaylandProtocols)
set_package_properties(Wayland PROPERTIES
TYPE REQUIRED)

View File

@ -4,6 +4,6 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(Qt@QT_MAJOR_VERSION@Gui "@QT_MIN_VERSION@")
find_dependency(Qt5Gui "@QT_MIN_VERSION@")
include("${CMAKE_CURRENT_LIST_DIR}/LayerShellQtTargets.cmake")

View File

@ -1,14 +0,0 @@
maintainer:
- vladz
description: Layer Shell Qt
platforms:
- name: Linux
- name: FreeBSD
portingAid: false
deprecated: false
release: true
group: Plasma
public_lib: true
public_source_dirs:
- src/interfaces

View File

@ -3,16 +3,8 @@
remove_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS)
add_library(LayerShellQtInterface)
if (QT_MAJOR_VERSION EQUAL "5")
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)
else()
qt6_generate_wayland_protocol_client_sources(LayerShellQtInterface FILES
${WaylandProtocols_DATADIR}/stable/xdg-shell/xdg-shell.xml
${CMAKE_CURRENT_SOURCE_DIR}/wlr-layer-shell-unstable-v1.xml
)
endif()
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)
ecm_qt_declare_logging_category(LAYER_SHELL_SOURCES
HEADER
@ -23,25 +15,19 @@ ecm_qt_declare_logging_category(LAYER_SHELL_SOURCES
layershellqt
)
target_sources(LayerShellQtInterface PRIVATE qwaylandlayersurface.cpp interfaces/window.cpp interfaces/shell.cpp qwaylandlayershellintegration.cpp qwaylandlayershell.cpp ${LAYER_SHELL_SOURCES})
target_link_libraries(LayerShellQtInterface PRIVATE Qt::Gui Qt::WaylandClientPrivate Wayland::Client PkgConfig::XKBCOMMON)
if (TARGET Qt::XkbCommonSupportPrivate)
target_link_libraries(LayerShellQtInterface PRIVATE Qt::XkbCommonSupportPrivate)
endif()
add_library(LayerShellQtInterface SHARED qwaylandlayersurface.cpp interfaces/window.cpp interfaces/shell.cpp qwaylandlayershellintegration.cpp qwaylandlayershell.cpp ${LAYER_SHELL_SOURCES})
target_link_libraries(LayerShellQtInterface PRIVATE Qt::Gui Qt::WaylandClientPrivate Qt::XkbCommonSupportPrivate Wayland::Client)
target_include_directories(LayerShellQtInterface PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/LayerShellQt>"
INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR}/>"
)
set_target_properties(LayerShellQtInterface PROPERTIES VERSION ${LAYERSHELLQT_VERSION}
set_target_properties(LayerShellQtInterface PROPERTIES VERSION ${LAYERSHELLQT_VERSION_STRING}
SOVERSION ${LAYERSHELLQT_SOVERSION}
EXPORT_NAME Interface
)
add_library(layer-shell SHARED qwaylandlayershellintegrationplugin.cpp)
target_link_libraries(layer-shell LayerShellQtInterface Qt::WaylandClient Qt::WaylandClientPrivate Wayland::Client PkgConfig::XKBCOMMON)
if (TARGET Qt::XkbCommonSupportPrivate)
target_link_libraries(layer-shell Qt::XkbCommonSupportPrivate)
endif()
target_link_libraries(layer-shell LayerShellQtInterface Qt::WaylandClient Qt::WaylandClientPrivate Qt::XkbCommonSupportPrivate Wayland::Client)
ecm_generate_headers(LayerShellQt_HEADERS
HEADER_NAMES
@ -59,7 +45,7 @@ generate_export_header(LayerShellQtInterface
)
install(TARGETS layer-shell
LIBRARY DESTINATION ${KDE_INSTALL_QTPLUGINDIR}/wayland-shell-integration)
LIBRARY DESTINATION ${QT_PLUGIN_INSTALL_DIR}/wayland-shell-integration)
install(TARGETS LayerShellQtInterface EXPORT LayerShellQtTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})

View File

@ -18,3 +18,51 @@ void Shell::useLayerShell()
qCDebug(LAYERSHELLQT) << "Unable to set QT_WAYLAND_SHELL_INTEGRATION=layer-shell";
}
}
struct Defaults {
QString scope = QStringLiteral("normal");
Window::Anchors anchors = {Window::AnchorTop | Window::AnchorBottom | Window::AnchorLeft | Window::AnchorRight};
Window::Layer layer = Window::LayerTop;
QMargins margins;
};
Q_GLOBAL_STATIC(Defaults, s_defaults);
void Shell::setDefaultScope(const QString &scope)
{
s_defaults->scope = scope;
}
QString Shell::defaultScope()
{
return s_defaults->scope;
}
void Shell::setDefaultLayer(Window::Layer defaultLayer)
{
s_defaults->layer = defaultLayer;
}
Window::Layer Shell::defaultLayer()
{
return s_defaults->layer;
}
void Shell::setDefaultAnchors(Window::Anchors anchors)
{
s_defaults->anchors = anchors;
}
Window::Anchors Shell::defaultAnchors()
{
return s_defaults->anchors;
}
void Shell::setDefaultMargins(const QMargins &margins)
{
s_defaults->margins = margins;
}
QMargins Shell::defaultMargins()
{
return s_defaults->margins;
}

View File

@ -20,6 +20,18 @@ class LAYERSHELLQT_EXPORT Shell
{
public:
static void useLayerShell();
static void setDefaultMargins(const QMargins &margins);
static QMargins defaultMargins();
static void setDefaultScope(const QString &scope);
static QString defaultScope();
static void setDefaultLayer(Window::Layer defaultLayer);
static Window::Layer defaultLayer();
static void setDefaultAnchors(Window::Anchors defaultAnchors);
static Window::Anchors defaultAnchors();
};
}

View File

@ -15,145 +15,58 @@ using namespace LayerShellQt;
class LayerShellQt::WindowPrivate
{
public:
WindowPrivate(QWindow *window)
: parentWindow(window)
WindowPrivate(QWaylandLayerSurface *surface)
: surface(surface)
{
}
QWindow *parentWindow;
QString scope = QStringLiteral("window");
Window::Anchors anchors = {Window::AnchorTop | Window::AnchorBottom | Window::AnchorLeft | Window::AnchorRight};
int32_t exclusionZone = 0;
Window::KeyboardInteractivity keyboardInteractivity = Window::KeyboardInteractivityExclusive;
Window::Layer layer = Window::LayerTop;
QMargins margins;
QWaylandLayerSurface *getSurface() const;
QPointer<QScreen> desiredOutput;
QWaylandLayerSurface *const surface;
};
static QMap<QWindow *, Window *> s_map;
Window::~Window() = default;
Window::~Window()
void Window::setAnchor(Anchor anchor)
{
s_map.remove(d->parentWindow);
}
void Window::setAnchors(Anchors anchors)
{
d->anchors = anchors;
if (auto surface = d->getSurface()) {
surface->setAnchor(anchors);
}
}
Window::Anchors Window::anchors() const
{
return d->anchors;
d->surface->setAnchor(anchor);
}
void Window::setExclusiveZone(int32_t zone)
{
d->exclusionZone = zone;
if (auto surface = d->getSurface()) {
surface->setExclusiveZone(zone);
}
}
int32_t Window::exclusionZone() const
{
return d->exclusionZone;
d->surface->setExclusiveZone(zone);
}
void Window::setMargins(const QMargins &margins)
{
d->margins = margins;
if (auto surface = d->getSurface()) {
surface->setMargins(margins);
}
d->surface->setMargins(margins);
}
QMargins Window::margins() const
void Window::setKeyboardInteractivity(bool enabled)
{
return d->margins;
}
void Window::setKeyboardInteractivity(KeyboardInteractivity interactivity)
{
d->keyboardInteractivity = interactivity;
if (auto surface = d->getSurface()) {
surface->setKeyboardInteractivity(interactivity);
}
}
Window::KeyboardInteractivity Window::keyboardInteractivity() const
{
return d->keyboardInteractivity;
d->surface->setKeyboardInteractivity(enabled);
}
void Window::setLayer(Layer layer)
{
d->layer = layer;
if (auto surface = d->getSurface()) {
surface->setLayer(layer);
}
d->surface->setLayer(layer);
}
void Window::setScope(const QString &scope)
Window::Window(WindowPrivate *d)
: d(d)
{
d->scope = scope;
// this is static and must be set before the platform window is created
}
QString Window::scope() const
{
return d->scope;
}
Window::Layer Window::layer() const
{
return d->layer;
}
QScreen *Window::desiredOutput() const
{
return d->desiredOutput;
}
void Window::setDesiredOutput(QScreen *output)
{
d->desiredOutput = output;
}
Window::Window(QWindow *window)
: QObject(window)
, d(new WindowPrivate(window))
{
s_map.insert(d->parentWindow, this);
}
Window *Window::get(QWindow *window)
{
auto layerShellWindow = s_map.value(window);
if (layerShellWindow) {
return layerShellWindow;
}
return new Window(window);
}
QWaylandLayerSurface *WindowPrivate::getSurface() const
{
if (!parentWindow) {
return nullptr;
}
auto ww = dynamic_cast<QtWaylandClient::QWaylandWindow *>(parentWindow->handle());
auto ww = dynamic_cast<QtWaylandClient::QWaylandWindow *>(window->handle());
if (!ww) {
qCDebug(LAYERSHELLQT) << "window not a wayland window" << parentWindow;
qCDebug(LAYERSHELLQT) << "window not a wayland window" << window;
return nullptr;
}
QWaylandLayerSurface *s = qobject_cast<QWaylandLayerSurface *>(ww->shellSurface());
if (!s) {
qCDebug(LAYERSHELLQT) << "window not using wlr-layer-shell" << parentWindow << ww->shellSurface();
qCDebug(LAYERSHELLQT) << "window not using wlr-layer-shell" << window << ww->shellSurface();
return nullptr;
}
return s;
return new Window(new WindowPrivate(s));
}

View File

@ -9,7 +9,6 @@
#define LAYERSHELLQTWINDOW_H
#include <QObject>
#include <QScreen>
#include <QWindow>
#include "layershellqt_export.h"
@ -25,10 +24,10 @@ 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
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);
Q_DECLARE_FLAGS(Anchors, Anchor)
@ -44,57 +43,16 @@ public:
};
Q_ENUM(Layer)
/**
* This enum type is used to specify how the layer surface handles keyboard focus.
*/
enum KeyboardInteractivity {
KeyboardInteractivityNone = 0,
KeyboardInteractivityExclusive = 1,
KeyboardInteractivityOnDemand = 2,
};
Q_ENUM(KeyboardInteractivity)
void setAnchors(Anchors anchor);
Anchors anchors() const;
void setAnchor(Anchor anchor);
void setExclusiveZone(int32_t zone);
int32_t exclusionZone() const;
void setMargins(const QMargins &margins);
QMargins margins() const;
void setKeyboardInteractivity(KeyboardInteractivity interactivity);
KeyboardInteractivity keyboardInteractivity() const;
void setKeyboardInteractivity(bool enabled);
void setLayer(Layer layer);
Layer layer() const;
/**
* If set, the compositor will try to put the window on the given screen.
* If its not set, then the compositor will decide where to put the window.
* Under normal circumstances, this should be the active output.
*/
void setDesiredOutput(QScreen *output);
QScreen *desiredOutput() const;
/**
* Sets a string based identifier for this window.
* This may be used by a compositor to determine stacking
* order within a given layer.
*
* May also be referred to as a role
*/
void setScope(const QString &scope);
QString scope() const;
/**
* Gets the LayerShell Window for a given Qt Window
* Ownership is not transferred
*/
static Window *get(QWindow *window);
private:
Window(QWindow *window);
Window(WindowPrivate *d);
QScopedPointer<WindowPrivate> d;
};

View File

@ -10,8 +10,8 @@
namespace LayerShellQt
{
QWaylandLayerShell::QWaylandLayerShell(::wl_registry *registry, uint32_t id, uint32_t version)
: QtWayland::zwlr_layer_shell_v1(registry, id, version)
QWaylandLayerShell::QWaylandLayerShell(QtWayland::zwlr_layer_shell_v1 *shell)
: QtWayland::zwlr_layer_shell_v1(shell->object())
{
}

View File

@ -20,8 +20,8 @@ namespace LayerShellQt
class LAYERSHELLQT_EXPORT QWaylandLayerShell : public QtWayland::zwlr_layer_shell_v1
{
public:
QWaylandLayerShell(::wl_registry *registry, uint32_t id, uint32_t version);
~QWaylandLayerShell() override;
QWaylandLayerShell(QtWayland::zwlr_layer_shell_v1 *shell);
virtual ~QWaylandLayerShell();
QWaylandLayerSurface *createLayerSurface(QtWaylandClient::QWaylandWindow *window);
// TODO: Popups

View File

@ -18,15 +18,9 @@ QWaylandLayerShellIntegration::QWaylandLayerShellIntegration()
{
}
QWaylandLayerShellIntegration::~QWaylandLayerShellIntegration()
{
}
bool QWaylandLayerShellIntegration::initialize(QtWaylandClient::QWaylandDisplay *display)
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QWaylandShellIntegration::initialize(display);
#endif
display->addRegistryListener(registryLayer, this);
return m_layerShell != nullptr;
}
@ -41,7 +35,7 @@ void QWaylandLayerShellIntegration::registryLayer(void *data, struct wl_registry
QWaylandLayerShellIntegration *shell = static_cast<QWaylandLayerShellIntegration *>(data);
if (interface == zwlr_layer_shell_v1_interface.name)
shell->m_layerShell.reset(new QWaylandLayerShell(registry, id, std::min(version, 4u)));
shell->m_layerShell = new QWaylandLayerShell(new QtWayland::zwlr_layer_shell_v1(registry, id, std::min(version, 3u)));
}
}

View File

@ -21,7 +21,6 @@ class LAYERSHELLQT_EXPORT QWaylandLayerShellIntegration : public QtWaylandClient
{
public:
QWaylandLayerShellIntegration();
~QWaylandLayerShellIntegration() override;
bool initialize(QtWaylandClient::QWaylandDisplay *display) override;
QtWaylandClient::QWaylandShellSurface *createShellSurface(QtWaylandClient::QWaylandWindow *window) override;
@ -29,7 +28,7 @@ public:
private:
static void registryLayer(void *data, struct wl_registry *registry, uint32_t id, const QString &interface, uint32_t version);
QScopedPointer<QWaylandLayerShell> m_layerShell;
QWaylandLayerShell *m_layerShell = nullptr;
};
}

View File

@ -6,7 +6,6 @@
*/
#include "interfaces/shell.h"
#include "layershellqt_logging.h"
#include "qwaylandlayershell_p.h"
#include "qwaylandlayersurface_p.h"
@ -18,40 +17,24 @@ namespace LayerShellQt
{
QWaylandLayerSurface::QWaylandLayerSurface(QWaylandLayerShell *shell, QtWaylandClient::QWaylandWindow *window)
: QtWaylandClient::QWaylandShellSurface(window)
, QtWayland::zwlr_layer_surface_v1()
, QtWayland::zwlr_layer_surface_v1(
shell->get_layer_surface(window->waylandSurface()->object(), window->waylandScreen()->output(), Shell::defaultLayer(), Shell::defaultScope()))
{
LayerShellQt::Window *interface = Window::get(window->window());
Q_ASSERT(interface);
const auto anchors = Shell::defaultAnchors();
set_anchor(anchors);
wl_output *output = nullptr;
QScreen *screen = interface->desiredOutput();
if (screen) {
auto waylandScreen = dynamic_cast<QtWaylandClient::QWaylandScreen *>(screen->handle());
// Qt will always assign a screen to a window, but if the compositor has no screens available a dummy QScreen object is created
// this will not cast to a QWaylandScreen
if (!waylandScreen) {
qCWarning(LAYERSHELLQT) << "Creating a layer shell for placeholder screen. This will be positioned incorrectly";
} else {
output = waylandScreen->output();
}
if (!Shell::defaultMargins().isNull()) {
setMargins(Shell::defaultMargins());
}
init(shell->get_layer_surface(window->waylandSurface()->object(), output, interface->layer(), interface->scope()));
Window::Anchors anchors = interface->anchors();
set_anchor(interface->anchors());
setMargins(interface->margins());
setKeyboardInteractivity(interface->keyboardInteractivity());
setExclusiveZone(interface->exclusionZone());
QSize size = window->surfaceSize();
if ((anchors & Window::AnchorLeft) && (anchors & Window::AnchorRight)) {
if (anchors & Window::AnchorLeft && anchors & Window::AnchorRight) {
size.setWidth(0);
}
if ((anchors & Window::AnchorTop) && (anchors & Window::AnchorBottom)) {
if (anchors & Window::AnchorTop && anchors & Window::AnchorBottom) {
size.setHeight(0);
}
if (size.isValid() && size != QSize(0, 0)) {
if (size.isValid() && size != QSize(0,0)) {
set_size(size.width(), size.height());
}
}
@ -102,9 +85,9 @@ void QWaylandLayerSurface::setMargins(const QMargins &margins)
set_margin(margins.top(), margins.right(), margins.bottom(), margins.left());
}
void QWaylandLayerSurface::setKeyboardInteractivity(uint32_t interactivity)
void QWaylandLayerSurface::setKeyboardInteractivity(bool enabled)
{
set_keyboard_interactivity(interactivity);
set_keyboard_interactivity(enabled);
}
void QWaylandLayerSurface::setLayer(uint32_t layer)

View File

@ -23,7 +23,7 @@ class LAYERSHELLQT_EXPORT QWaylandLayerSurface : public QtWaylandClient::QWaylan
Q_OBJECT
public:
QWaylandLayerSurface(QWaylandLayerShell *shell, QtWaylandClient::QWaylandWindow *window);
~QWaylandLayerSurface() override;
virtual ~QWaylandLayerSurface();
bool isExposed() const override
{
@ -33,7 +33,7 @@ public:
void setAnchor(uint32_t anchor);
void setExclusiveZone(int32_t zone);
void setMargins(const QMargins &margins);
void setKeyboardInteractivity(uint32_t interactivity);
void setKeyboardInteractivity(bool enabled);
void setLayer(uint32_t layer);
void applyConfigure() override;

View File

@ -25,7 +25,7 @@
THIS SOFTWARE.
</copyright>
<interface name="zwlr_layer_shell_v1" version="4">
<interface name="zwlr_layer_shell_v1" version="3">
<description summary="create surfaces that are layers of the desktop">
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
@ -100,7 +100,7 @@
</request>
</interface>
<interface name="zwlr_layer_surface_v1" version="4">
<interface name="zwlr_layer_surface_v1" version="3">
<description summary="layer metadata interface">
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
@ -203,85 +203,21 @@
<arg name="left" type="int"/>
</request>
<enum name="keyboard_interactivity">
<description summary="types of keyboard interaction possible for a layer shell surface">
Types of keyboard interaction possible for layer shell surfaces. The
rationale for this is twofold: (1) some applications are not interested
in keyboard events and not allowing them to be focused can improve the
desktop experience; (2) some applications will want to take exclusive
keyboard focus.
</description>
<entry name="none" value="0">
<description summary="no keyboard focus is possible">
This value indicates that this surface is not interested in keyboard
events and the compositor should never assign it the keyboard focus.
This is the default value, set for newly created layer shell surfaces.
This is useful for e.g. desktop widgets that display information or
only have interaction with non-keyboard input devices.
</description>
</entry>
<entry name="exclusive" value="1">
<description summary="request exclusive keyboard focus">
Request exclusive keyboard focus if this surface is above the shell surface layer.
For the top and overlay layers, the seat will always give
exclusive keyboard focus to the top-most layer which has keyboard
interactivity set to exclusive. If this layer contains multiple
surfaces with keyboard interactivity set to exclusive, the compositor
determines the one receiving keyboard events in an implementation-
defined manner. In this case, no guarantee is made when this surface
will receive keyboard focus (if ever).
For the bottom and background layers, the compositor is allowed to use
normal focus semantics.
This setting is mainly intended for applications that need to ensure
they receive all keyboard events, such as a lock screen or a password
prompt.
</description>
</entry>
<entry name="on_demand" value="2" since="4">
<description summary="request regular keyboard focus semantics">
This requests the compositor to allow this surface to be focused and
unfocused by the user in an implementation-defined manner. The user
should be able to unfocus this surface even regardless of the layer
it is on.
Typically, the compositor will want to use its normal mechanism to
manage keyboard focus between layer shell surfaces with this setting
and regular toplevels on the desktop layer (e.g. click to focus).
Nevertheless, it is possible for a compositor to require a special
interaction to focus or unfocus layer shell surfaces (e.g. requiring
a click even if focus follows the mouse normally, or providing a
keybinding to switch focus between layers).
This setting is mainly intended for desktop shell components (e.g.
panels) that allow keyboard interaction. Using this option can allow
implementing a desktop shell that can be fully usable without the
mouse.
</description>
</entry>
</enum>
<request name="set_keyboard_interactivity">
<description summary="requests keyboard events">
Set how keyboard events are delivered to this surface. By default,
layer shell surfaces do not receive keyboard events; this request can
be used to change this.
This setting is inherited by child surfaces set by the get_popup
request.
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.
Keyboard interactivity is double-buffered, see wl_surface.commit.
Events is double-buffered, see wl_surface.commit.
</description>
<arg name="keyboard_interactivity" type="uint" enum="keyboard_interactivity"/>
<arg name="keyboard_interactivity" type="uint"/>
</request>
<request name="get_popup">
@ -366,7 +302,6 @@
<entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/>
<entry name="invalid_size" value="1" summary="size is invalid"/>
<entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/>
<entry name="invalid_keyboard_interactivity" value="3" summary="keyboard interactivity is invalid"/>
</enum>
<enum name="anchor" bitfield="true">

View File

@ -5,15 +5,8 @@
*/
#include <QCommandLineParser>
#include <QGuiApplication>
#include <QPainter>
#include <QRasterWindow>
#include <QTimer>
#include <QWindow>
#include <QMetaEnum>
#include <QQmlApplicationEngine>
#include <interfaces/shell.h>
#include <interfaces/window.h>
@ -40,15 +33,6 @@ T stringToEnum(QMetaEnum metaEnum, const QString &str)
return ret;
}
class BasicWindow : public QRasterWindow
{
void paintEvent(QPaintEvent *)
{
QPainter p(this);
p.fillRect(QRect(0, 0, width(), height()), Qt::red);
}
};
int main(int argc, char **argv)
{
Shell::useLayerShell();
@ -69,40 +53,38 @@ int main(int argc, char **argv)
QStringLiteral("One of ") + enumsToStringList(layerMetaEnum).join(QLatin1String("|")),
QStringLiteral("layer"),
QStringLiteral("LayerTop"));
QCommandLineOption widthOption(QStringLiteral("width"), QStringLiteral("Width of the window"), QStringLiteral("pixels"), QStringLiteral("0"));
QCommandLineOption heightOption(QStringLiteral("height"), QStringLiteral("Height of the window"), QStringLiteral("pixels"), QStringLiteral("0"));
parser.addOptions({marginsOption, scopeOption, anchorsOption, layerOption, widthOption, heightOption});
parser.addOptions({marginsOption, scopeOption, anchorsOption, layerOption});
parser.addHelpOption();
parser.process(app);
BasicWindow window;
LayerShellQt::Window *layerShell = LayerShellQt::Window::get(&window);
static int margins = 0;
if (parser.isSet(marginsOption)) {
int margins = parser.value(marginsOption).toInt();
layerShell->setMargins({margins, margins, margins, margins});
margins = parser.value(marginsOption).toInt();
Shell::setDefaultMargins({margins, margins, margins, margins});
}
if (parser.isSet(scopeOption)) {
layerShell->setScope(parser.value(scopeOption));
Shell::setDefaultScope(parser.value(scopeOption));
}
if (parser.isSet(layerOption)) {
layerShell->setLayer(Window::Layer(layerMetaEnum.keyToValue(qPrintable(parser.value(layerOption)))));
Shell::setDefaultLayer(Window::Layer(layerMetaEnum.keyToValue(qPrintable(parser.value(layerOption)))));
}
if (parser.isSet(anchorsOption)) {
layerShell->setAnchors(stringToEnum<Window::Anchors>(anchorMetaEnum, parser.value(anchorsOption)));
}
if (parser.isSet(widthOption)) {
window.setWidth(parser.value(widthOption).toInt());
}
if (parser.isSet(heightOption)) {
window.setHeight(parser.value(heightOption).toInt());
Shell::setDefaultAnchors(stringToEnum<Window::Anchors>(anchorMetaEnum, parser.value(anchorsOption)));
}
window.show();
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"));
// just so you don't block yourself out whilst testing
QTimer::singleShot(5000, &app, &QGuiApplication::quit);
return app.exec();
}