From 11a811061f1f3e8abf8386a55cbae0b0ba93100d Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 20 Apr 2021 15:27:43 +0300 Subject: [PATCH] Introduce KeyboardInteractivity enum --- src/interfaces/window.cpp | 10 ++-- src/interfaces/window.h | 14 ++++- src/qwaylandlayershellintegration.cpp | 2 +- src/qwaylandlayersurface.cpp | 4 +- src/qwaylandlayersurface_p.h | 2 +- src/wlr-layer-shell-unstable-v1.xml | 83 ++++++++++++++++++++++++--- 6 files changed, 95 insertions(+), 20 deletions(-) diff --git a/src/interfaces/window.cpp b/src/interfaces/window.cpp index 9ca3453..81e0d39 100644 --- a/src/interfaces/window.cpp +++ b/src/interfaces/window.cpp @@ -24,7 +24,7 @@ public: QString scope = QStringLiteral("window"); Window::Anchors anchors = {Window::AnchorTop | Window::AnchorBottom | Window::AnchorLeft | Window::AnchorRight}; int32_t exclusionZone = 0; - bool keyboardInteractivity = true; + Window::KeyboardInteractivity keyboardInteractivity = Window::KeyboardInteractivityExclusive; Window::Layer layer = Window::LayerTop; QMargins margins; QWaylandLayerSurface *getSurface() const; @@ -76,15 +76,15 @@ QMargins Window::margins() const return d->margins; } -void Window::setKeyboardInteractivity(bool enabled) +void Window::setKeyboardInteractivity(KeyboardInteractivity interactivity) { - d->keyboardInteractivity = enabled; + d->keyboardInteractivity = interactivity; if (auto surface = d->getSurface()) { - surface->setKeyboardInteractivity(enabled); + surface->setKeyboardInteractivity(interactivity); } } -bool Window::keyboardInteractivity() const +Window::KeyboardInteractivity Window::keyboardInteractivity() const { return d->keyboardInteractivity; } diff --git a/src/interfaces/window.h b/src/interfaces/window.h index 1c3867b..33c46b0 100644 --- a/src/interfaces/window.h +++ b/src/interfaces/window.h @@ -43,6 +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; @@ -52,8 +62,8 @@ public: void setMargins(const QMargins &margins); QMargins margins() const; - void setKeyboardInteractivity(bool enabled); - bool keyboardInteractivity() const; + void setKeyboardInteractivity(KeyboardInteractivity interactivity); + KeyboardInteractivity keyboardInteractivity() const; void setLayer(Layer layer); Layer layer() const; diff --git a/src/qwaylandlayershellintegration.cpp b/src/qwaylandlayershellintegration.cpp index cdf3e91..bb738f2 100644 --- a/src/qwaylandlayershellintegration.cpp +++ b/src/qwaylandlayershellintegration.cpp @@ -35,7 +35,7 @@ void QWaylandLayerShellIntegration::registryLayer(void *data, struct wl_registry QWaylandLayerShellIntegration *shell = static_cast(data); if (interface == zwlr_layer_shell_v1_interface.name) - shell->m_layerShell = new QWaylandLayerShell(new QtWayland::zwlr_layer_shell_v1(registry, id, std::min(version, 3u))); + shell->m_layerShell = new QWaylandLayerShell(new QtWayland::zwlr_layer_shell_v1(registry, id, std::min(version, 4u))); } } diff --git a/src/qwaylandlayersurface.cpp b/src/qwaylandlayersurface.cpp index 72654eb..c4270b1 100644 --- a/src/qwaylandlayersurface.cpp +++ b/src/qwaylandlayersurface.cpp @@ -89,9 +89,9 @@ void QWaylandLayerSurface::setMargins(const QMargins &margins) set_margin(margins.top(), margins.right(), margins.bottom(), margins.left()); } -void QWaylandLayerSurface::setKeyboardInteractivity(bool enabled) +void QWaylandLayerSurface::setKeyboardInteractivity(uint32_t interactivity) { - set_keyboard_interactivity(enabled); + set_keyboard_interactivity(interactivity); } void QWaylandLayerSurface::setLayer(uint32_t layer) diff --git a/src/qwaylandlayersurface_p.h b/src/qwaylandlayersurface_p.h index 40d9e0e..91fce74 100644 --- a/src/qwaylandlayersurface_p.h +++ b/src/qwaylandlayersurface_p.h @@ -33,7 +33,7 @@ public: void setAnchor(uint32_t anchor); void setExclusiveZone(int32_t zone); void setMargins(const QMargins &margins); - void setKeyboardInteractivity(bool enabled); + void setKeyboardInteractivity(uint32_t interactivity); void setLayer(uint32_t layer); void applyConfigure() override; diff --git a/src/wlr-layer-shell-unstable-v1.xml b/src/wlr-layer-shell-unstable-v1.xml index 0736a45..b53f7a8 100644 --- a/src/wlr-layer-shell-unstable-v1.xml +++ b/src/wlr-layer-shell-unstable-v1.xml @@ -25,7 +25,7 @@ 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 @@ -100,7 +100,7 @@ - + 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,21 +203,85 @@ + + + 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. + + + + + 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. + + + + + 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. + + + + + 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. + + + + - 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. + 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. 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. + Keyboard interactivity is double-buffered, see wl_surface.commit. - + @@ -302,6 +366,7 @@ +