Louvre  v2.9.0-1
C++ library for Wayland compositors
Classes | Public Types | Public Member Functions | List of all members
LLayerRole Class Reference

Layer role for surfaces. More...

+ Inheritance diagram for LLayerRole:

Classes

struct  Atoms
 Atomically changing properties. More...
 

Public Types

enum  KeyboardInteractivity
 Defines the keyboard interactivity modes for a surface. More...
 
enum  AtomChanges : UInt32
 Indicates which properties have changed during an atomsChanged() event. More...
 
- Public Types inherited from LBaseSurfaceRole
enum  CommitOrigin
 Commit origin. More...
 
- Public Types inherited from LFactoryObject
enum class  Type : Int32
 Base factory object types. More...
 

Public Member Functions

 LLayerRole (const void *params) noexcept
 Constructor of the LLayerRole class. More...
 
 ~LLayerRole () noexcept
 Destructor of the LLayerRole class. More...
 
virtual const LPointrolePos () const override
 LLayerRole surface position. More...
 
virtual void configureRequest ()
 Request to configure the surface size. More...
 
void configureSize (const LSize &size) noexcept
 Configure size. More...
 
virtual void atomsChanged (LBitset< AtomChanges > changes, const Atoms &prevAtoms)
 Notify property changes. More...
 
const Atomsatoms () const noexcept
 Retrieves the current atomic properties. More...
 
const LSizesize () const noexcept
 Surface size hint. More...
 
LBitset< LEdgeanchor () const noexcept
 Anchor edges. More...
 
const LExclusiveZoneexclusiveZone () const noexcept
 Exclusive Zone. More...
 
Int32 exclusiveZoneSize () const noexcept
 Size of the exclusive zone. More...
 
const LMarginsmargins () const noexcept
 Margins. More...
 
KeyboardInteractivity keyboardInteractivity () const noexcept
 The current keyboard interactivity mode. More...
 
LEdge exclusiveEdge () const noexcept
 Exclusive edge. More...
 
LSurfaceLayer layer () const noexcept
 Retrieves the layer to which the surface is assigned. More...
 
LOutputexclusiveOutput () const override
 Retrieves the current output. More...
 
void setExclusiveOutput (LOutput *output) noexcept
 Sets the current output. More...
 
const std::string & scope () noexcept
 Scope. More...
 
void close () noexcept
 Requests the client to close the LLayerRole. More...
 
- Public Member Functions inherited from LBaseSurfaceRole
 LBaseSurfaceRole (LFactoryObject::Type type, LResource *resource, LSurface *surface, UInt32 roleId) noexcept
 Constructor of LBaseSurfaceRole class. More...
 
 ~LBaseSurfaceRole ()
 The LBaseSurfaceRole class destructor. More...
 
UInt32 roleId () const noexcept
 Role ID. More...
 
LSurfacesurface () const noexcept
 Returns the surface that has acquired the role provided in the constructor. More...
 
LResourceresource () const
 Returns the Wayland resource for this role given in the constructor. More...
 
LClientclient () const noexcept
 Client owner of the surface role. More...
 
- Public Member Functions inherited from LFactoryObject
Type factoryObjectType () const noexcept
 Gets the base factory object type. More...
 
- Public Member Functions inherited from LObject
 LObject (const LObject &) noexcept
 Copy constructor. More...
 
LObjectoperator= (const LObject &) noexcept
 Assignment operator (each object has its own individual LWeak reference count). More...
 
void setUserData (UIntPtr data) const noexcept
 Store an unsigned integer value/pointer. More...
 
UIntPtr userData () const noexcept
 Retrieves the stored unsigned integer value/pointer. More...
 

Additional Inherited Members

- Protected Member Functions inherited from LBaseSurfaceRole
virtual bool acceptCommitRequest (CommitOrigin origin)
 Asks if the surface commit should be processed. More...
 
virtual void handleSurfaceBufferAttach (wl_resource *buffer, Int32 x, Int32 y)
 Notifies a new surface buffer attachment. More...
 
virtual void handleSurfaceOffset (Int32 x, Int32 y)
 Notifies a surface buffer offset change. More...
 
virtual void handleParentCommit ()
 Notifies a parent surface commit. More...
 
virtual void handleParentMappingChange ()
 Notifies when the mapping state of the parent surface changes. More...
 
virtual void handleParentChange ()
 Notifies when the parent surface changes. More...
 
- Protected Member Functions inherited from LObject
 LObject () noexcept=default
 Constructor of the LObject class. More...
 
virtual ~LObject () noexcept
 Destructor of the LObject class. More...
 
void notifyDestruction () noexcept
 Notifies the object destruction. More...
 
- Protected Attributes inherited from LBaseSurfaceRole
LPoint m_rolePos
 Variable that stores the surface position given the role. More...
 

Detailed Description

Layer role for surfaces.

The LLayerRole is used by clients to create various desktop shell components such as a wallpaper, panels, docks, notifications, etc.
It is part of the wlr_layer_shell protocol. For a comprehensive understanding of each concept, refer to the protocol documentation.

Layer

LLayerRole surfaces can be assigned to all layers defined in LSurfaceLayer, except for LLayerMiddle .
This assignment affects the Z-order, determining how the compositor renders them. The list of surfaces created by clients, accessible through LCompositor::surfaces(), reflects the order they should be rendered, from bottom to top.
It's also possible to retrieve the list of surfaces for specific layers using LCompositor::layer().

Note
The order of independent layers follows the same sequence as LCompositor::surfaces().
See also
LSurface::layer(), LSurface::layerChanged() and LSurface::orderChanged().

Positioning

LLayerRole surfaces are always positioned relative to a specific LOutput, which can be defined by the client at creation time or replaced later with setExclusiveOutput(). If the client does not specify one, exclusiveOutput() is initially nullptr. The default implementation of configureRequest() assigns the current cursor output in such cases.

Clients can anchor the surface to one or multiple edges of the output, with optional additional margins.
Position calculation is simplified by utilizing an instance of LExclusiveZone (exclusiveZone()). The property LExclusiveZone::rect() specifies a rect within the output where the surface should be positioned, and it does not always denote an exclusive zone.

For example, when exclusiveZoneSize() equals 0, LExclusiveZone::rect() contains the available space for placing the surface, preventing occlusion of other exclusive zones.

See also
LExclusiveZone and the default implementation of rolePos().

Exclusive Zone

LLayerRole surfaces can define a size from the edge they are anchored to, to be considered as an exclusive zone, requesting the compositor to prevent occlusion by other surfaces. Since each LLayerRole has its own LExclusiveZone instance, the surfaces positions and size is automatically updated as well as the LOutput::availableGeometry() which can be used, for example, to properly configure LToplevelRole or other types of surfaces.

Exclusive zones have different levels of priority, which are defined by the order of the LOutput::exclusiveZones() list. The ones first in the list have higher priority, causing lower priority zones to be moved or resized to prevent occlusion. To modify the order of the list, use LExclusiveZone::insertAfter().

Note
Whenever the LExclusiveZone::rect() changes—due to alterations in other surfaces' exclusive zones, the configureRequest() function is triggered. Here, the surface size should be readjusted to avoid obstructing other exclusive zones with higher priority.

Size

Upon creation, clients invoke configureRequest(), where they expect the compositor to configure the surface with an appropriate size.
During the request, the size() property contains the size desired by the client. If one of its components is 0, it means the compositor should assign it.

See also
configureRequest().

Class Documentation

◆ Louvre::LLayerRole::Atoms

struct Louvre::LLayerRole::Atoms

Atomically changing properties.

This struct contains all properties related to LLayerRole whose changes should be handled atomically.

Using individual property change event listeners could cause issues related to the order in which they are emitted.
Therefore, in Wayland, the concept of a double-buffered state is often used, where current properties are replaced by pending properties atomically.

See also
atoms()
atomsChanged()
Class Members
LSize size LLayerRole::size()
LBitset< LEdge > anchor LLayerRole::anchor()
Int32 exclusiveZoneSize LLayerRole::exclusiveZoneSize()
LMargins margins LLayerRole::margins()
KeyboardInteractivity keyboardInteractivity LLayerRole::keyboardInteractivity()
LEdge exclusiveEdge LLayerRole::exclusiveEdge()
LSurfaceLayer layer LLayerRole::layer()

Member Enumeration Documentation

◆ KeyboardInteractivity

Defines the keyboard interactivity modes for a surface.

This enumeration specifies the different modes of keyboard interaction that a surface can have.

See also
keyboardInteractivity()
Enumerator
NoInteractivity 

The surface should not receive keyboard focus.

Exclusive 

The surface should grab and hold the keyboard focus exclusively.

See also
LKeyboard::setGrab()
OnDemand 

The surface should follow normal keyboard focus rules.

◆ AtomChanges

Indicates which properties have changed during an atomsChanged() event.

Enumerator
SizeChanged 

Indicates that size() has changed.

AnchorChanged 

Indicates that anchor() has changed.

ExclusiveZoneSizeChanged 

Indicates that the exclusiveZoneSize() has changed.

MarginsChanged 

Indicates that margins() have changed.

KeyboardInteractivityChanged 

Indicates that keyboardInteractivity() has changed.

LayerChanged 

Indicates that the layer() has changed.

ExclusiveEdgeChanged 

Indicates that the exclusiveEdge() has changed.

Constructor & Destructor Documentation

◆ LLayerRole()

LLayerRole ( const void *  params)
noexcept

Constructor of the LLayerRole class.

Parameters
paramsInternal parameters provided in LCompositor::createObjectRequest().

◆ ~LLayerRole()

~LLayerRole ( )
noexcept

Destructor of the LLayerRole class.

Invoked after LCompositor::onAnticipatedObjectDestruction().

Member Function Documentation

◆ rolePos()

virtual const LPoint& rolePos ( ) const
overridevirtual

LLayerRole surface position.

The default implementation positions the surface relative to its current exclusiveOutput(), taking into account its current anchor(), margins(), and the information provided by its exclusiveZone().

Default Implementation

{
// If no output has been assigned, use the user-defined position.
return surface()->pos();
if (anchor() == (LEdgeTop | LEdgeLeft))
{
}
else if (anchor() == (LEdgeTop | LEdgeRight))
{
m_rolePos.setX(exclusiveOutput()->pos().x() + exclusiveZone().rect().x()
+ exclusiveZone().rect().w() - surface()->size().w());
m_rolePos.setY(exclusiveOutput()->pos().y() + exclusiveZone().rect().y());
}
else if (anchor() == (LEdgeBottom | LEdgeRight))
{
m_rolePos.setX(exclusiveOutput()->pos().x() + exclusiveZone().rect().x()
+ exclusiveZone().rect().w() - surface()->size().w());
m_rolePos.setY(exclusiveOutput()->pos().y() + exclusiveZone().rect().y()
+ exclusiveZone().rect().h() - surface()->size().h());
}
else if (anchor() == (LEdgeBottom | LEdgeLeft))
{
m_rolePos.setX(exclusiveOutput()->pos().x() + exclusiveZone().rect().x());
m_rolePos.setY(exclusiveOutput()->pos().y() + exclusiveZone().rect().y()
+ exclusiveZone().rect().h() - surface()->size().h());
}
else if (anchor() == LEdgeTop || anchor() == (LEdgeLeft | LEdgeTop | LEdgeRight))
{
m_rolePos.setX(exclusiveOutput()->pos().x() + exclusiveZone().rect().x()
+ (exclusiveZone().rect().w() - surface()->size().w()) / 2 );
m_rolePos.setY(exclusiveOutput()->pos().y() + exclusiveZone().rect().y());
}
{
m_rolePos.setX(exclusiveOutput()->pos().x() + exclusiveZone().rect().x()
+ (exclusiveZone().rect().w() - surface()->size().w()) / 2 );
m_rolePos.setY(exclusiveOutput()->pos().y() + exclusiveZone().rect().y()
+ exclusiveZone().rect().h() - surface()->size().h());
}
else if (anchor() == LEdgeLeft || anchor() == (LEdgeBottom | LEdgeLeft | LEdgeTop))
{
m_rolePos.setX(exclusiveOutput()->pos().x() + exclusiveZone().rect().x());
m_rolePos.setY(exclusiveOutput()->pos().y() + exclusiveZone().rect().y()
+ (exclusiveZone().rect().h() - surface()->size().h()) / 2);
}
else if (anchor() == LEdgeRight || anchor() == (LEdgeBottom | LEdgeRight | LEdgeTop))
{
m_rolePos.setX(exclusiveOutput()->pos().x() + exclusiveZone().rect().x()
+ exclusiveZone().rect().w() - surface()->size().w());
m_rolePos.setY(exclusiveOutput()->pos().y() + exclusiveZone().rect().y()
+ (exclusiveZone().rect().h() - surface()->size().h()) / 2);
}
else
// Add extra margins.
return m_rolePos;
}
LSurface * surface() const noexcept
Returns the surface that has acquired the role provided in the constructor.
Definition: LBaseSurfaceRole.h:117
LPoint m_rolePos
Variable that stores the surface position given the role.
Definition: LBaseSurfaceRole.h:144
constexpr bool check(Flag flags) const noexcept
Check if at least one flag exists.
Definition: LBitset.h:86
const LRect & rect() const noexcept
Gets the calculated position and size of the exclusive zone in output-local surface coordinates.
Definition: LExclusiveZone.h:172
const LSize & size() const noexcept
Surface size hint.
Definition: LLayerRole.h:254
virtual const LPoint & rolePos() const override
LLayerRole surface position.
LBitset< LEdge > anchor() const noexcept
Anchor edges.
Definition: LLayerRole.h:264
const LMargins & margins() const noexcept
Margins.
Definition: LLayerRole.h:308
const LExclusiveZone & exclusiveZone() const noexcept
Exclusive Zone.
Definition: LLayerRole.h:282
LOutput * exclusiveOutput() const override
Retrieves the current output.
Definition: LLayerRole.h:360
const LPoint & pos() const noexcept
Gets the output position.
Definition: LOutput.cpp:359
constexpr T x() const noexcept
First component of the vector.
Definition: LPoint.h:37
constexpr void setX(T x) noexcept
Assigns the value to the first component of the vector.
Definition: LPoint.h:58
constexpr void setY(T y) noexcept
Assigns the value to the second component of the vector.
Definition: LPoint.h:61
constexpr T y() const noexcept
Second component of the vector.
Definition: LPoint.h:40
constexpr const LPointTemplate< T > & pos() const noexcept
2D vector given by the (x,y) components of the rectangle
Definition: LRect.h:128
constexpr const LPointTemplate< T > & size() const noexcept
2D vector given by the (w,h) components of the rectangle
Definition: LRect.h:131
const LPoint & pos() const noexcept
Position given by the compositor.
Definition: LSurface.cpp:319
const LSize & size() const noexcept
Surface size in surface coordinates.
Definition: LSurface.cpp:137
@ LEdgeLeft
The left edge.
Definition: LEdge.h:17
@ LEdgeRight
The right edge.
Definition: LEdge.h:18
@ LEdgeBottom
The bottom edge.
Definition: LEdge.h:16
@ LEdgeTop
The top edge.
Definition: LEdge.h:15
Int32 top
The top margin.
Definition: LMargins.h:14
LPointTemplate< Int32 > LPoint
2D vector of 32 bits integers
Definition: LNamespaces.h:247
Int32 left
The left margin.
Definition: LMargins.h:13
Int32 bottom
The bottom margin.
Definition: LMargins.h:16
Int32 right
The right margin.
Definition: LMargins.h:15

Implements LBaseSurfaceRole.

◆ configureRequest()

virtual void configureRequest ( )
virtual

Request to configure the surface size.

This request is triggered each time the LLayerRole surface is mapped, when its exclusiveZone() rect changes, or when the client sets one of the size() components to 0, indicating it expects the compositor to set the size. A configureSize() event must be sent to the client with the new suggested size.

Note
Clients are free to ignore the suggested size.

The default implementation configures the surface using the client's size() hint or the available exclusiveZone() space for components of size() that are 0, for components where both opposite edges are set in anchor() or if anchor() contains all edges or no edge at all.

Default Implementation

{
// If exclusive output is not set, assign the cursor's current output.
setExclusiveOutput(cursor()->output());
// The client-suggested size.
LSize newSize { size() };
/*
* LExclusiveZone calculates the single edge the surface is anchored to.
* It can also return 0 if the anchor() flags do not contain any edges or if they contain all edges.
*/
const LBitset<LEdge> edge { exclusiveZone().edge() };
/*
* If either the width or height of size() is 0, it indicates that the client expects the
* compositor to assign it. In such cases, or if the surface is anchored to both opposite edges,
* all edges or no edge, we assign it the entire available space of its exclusive zone.
* The client can choose a different size if desired. For more details see the LExclusiveZone doc.
*/
if (newSize.w() == 0 || edge == 0 || anchor().checkAll(LEdgeLeft | LEdgeRight))
newSize.setW(exclusiveZone().rect().w());
if (newSize.h() == 0 || edge == 0 || anchor().checkAll(LEdgeTop | LEdgeBottom))
newSize.setH(exclusiveZone().rect().h());
configureSize(newSize);
}
LEdge edge() const noexcept
Gets the current edge.
Definition: LExclusiveZone.h:124
void configureSize(const LSize &size) noexcept
Configure size.
Definition: LLayerRole.cpp:32
void setExclusiveOutput(LOutput *output) noexcept
Sets the current output.
Definition: LLayerRole.cpp:57
virtual void configureRequest()
Request to configure the surface size.
void sendOutputEnterEvent(LOutput *output) noexcept
Notify the client when the surface enters an output.
Definition: LSurface.cpp:332
LCursor * cursor() noexcept
Gets the compositor's cursor.
Definition: LCompositor.cpp:45
LPoint LSize
2D vector of 32 bits integers
Definition: LNamespaces.h:250

◆ configureSize()

void configureSize ( const LSize size)
noexcept

Configure size.

Asks the client to configure its surface with the specified size.
The size doesn't change immediately, see atomsChanged().

Note
This is just a suggestion, the client is free to ignore it.
Parameters
sizeThe size of the surface in coordinates.

◆ atomsChanged()

virtual void atomsChanged ( LBitset< AtomChanges changes,
const Atoms prevAtoms 
)
virtual

Notify property changes.

Notifies when one or more properties change.

See also
Atoms
Parameters
changesFlags indicating which properties have changed.
prevAtomsThe previous property values.

Default Implementation

void LLayerRole::atomsChanged(LBitset<AtomChanges> changes, const Atoms &prevAtoms)
{
L_UNUSED(prevAtoms);
if (changes.check(KeyboardInteractivityChanged))
{
{
case KeyboardInteractivity::NoInteractivity:
if (surface()->hasKeyboardFocus())
seat()->keyboard()->setFocus(nullptr);
if (surface()->hasKeyboardGrab())
seat()->keyboard()->setGrab(nullptr);
break;
case KeyboardInteractivity::OnDemand:
if (surface()->hasKeyboardGrab())
seat()->keyboard()->setGrab(nullptr);
break;
case KeyboardInteractivity::Exclusive:
break;
}
}
if (exclusiveOutput() && changes.check(
}
void setGrab(LSurface *surface)
Sets a keyboard grab.
Definition: LKeyboard.cpp:72
void setFocus(LSurface *surface)
Set keyboard focus.
Definition: LKeyboard.cpp:274
@ AnchorChanged
Indicates that anchor() has changed.
Definition: LLayerRole.h:104
@ ExclusiveZoneSizeChanged
Indicates that the exclusiveZoneSize() has changed.
Definition: LLayerRole.h:107
@ MarginsChanged
Indicates that margins() have changed.
Definition: LLayerRole.h:110
@ KeyboardInteractivityChanged
Indicates that keyboardInteractivity() has changed.
Definition: LLayerRole.h:113
@ ExclusiveEdgeChanged
Indicates that the exclusiveEdge() has changed.
Definition: LLayerRole.h:119
@ LayerChanged
Indicates that the layer() has changed.
Definition: LLayerRole.h:116
@ SizeChanged
Indicates that size() has changed.
Definition: LLayerRole.h:101
KeyboardInteractivity keyboardInteractivity() const noexcept
The current keyboard interactivity mode.
Definition: LLayerRole.h:318
virtual void atomsChanged(LBitset< AtomChanges > changes, const Atoms &prevAtoms)
Notify property changes.
void repaint() noexcept
Unlocks the rendering thread.
Definition: LOutput.cpp:305
LKeyboard * keyboard() const noexcept
Access to keyboard events.
Definition: LSeat.h:146
LSeat * seat() noexcept
Gets the compositor's seat.
Definition: LCompositor.cpp:40

◆ atoms()

const Atoms& atoms ( ) const
inlinenoexcept

Retrieves the current atomic properties.

The members of this struct can also be accessed using aliases such as size(), anchor(), margins(), etc.

Returns
Reference to the current atomic properties.

◆ size()

const LSize& size ( ) const
inlinenoexcept

Surface size hint.

Returns the surface size hint set by the client to indicate the desired surface size during a configureRequest().
If one of the components is 0, it means the compositor should assign it.

Note
This is just a hint, to retrieve the actual surface size, use LSurface::size().
Returns
The surface size hint.

◆ anchor()

LBitset<LEdge> anchor ( ) const
inlinenoexcept

Anchor edges.

Flags containing the edges of exclusiveOutput() to which the surface is anchored.

◆ exclusiveZone()

const LExclusiveZone& exclusiveZone ( ) const
inlinenoexcept

Exclusive Zone.

Each LLayerRole contains its own LExclusiveZone to simplify its positioning, as well as the positioning of other LLayerRole surfaces or UI elements using an LExclusiveZone.

The exclusive zone parameters are automatically updated by LLayerRole, but you can still reassign its output with setExclusiveOutput() and modify its order/priority with LExclusiveZone::insertAfter().
Zones with higher priority (listed at the beginning of LOutput::exclusiveZones()) take precedence, causing others to adjust their space accordingly.

Returns
A const reference to the exclusive zone.

◆ exclusiveZoneSize()

Int32 exclusiveZoneSize ( ) const
inlinenoexcept

Size of the exclusive zone.

  • If > 0, this represents the distance from the anchored edge considered exclusive. The exclusiveZone() size is automatically updated when this value changes, including the respective margin values as specified in the protocol.
  • If 0, the exclusiveZone() will move/resize to accommodate other exclusive zones but will not affect them.
  • If < 0, the exclusiveZone() will neither accommodate other zones nor affect them.

◆ margins()

const LMargins& margins ( ) const
inlinenoexcept

Margins.

Additional offset from the anchor edges added to the surface position.
This is used by clients, for example, to hide or show a dock.

◆ keyboardInteractivity()

KeyboardInteractivity keyboardInteractivity ( ) const
inlinenoexcept

The current keyboard interactivity mode.

See also
KeyboardInteractivity

◆ exclusiveEdge()

LEdge exclusiveEdge ( ) const
inlinenoexcept

Exclusive edge.

This is used by clients to disambiguate which edge is considered exclusive when the surface is anchored to a corner.

Even if the exclusiveZoneSize() is > 0, if the surface is anchored to an edge and this property is LEdgeNone, the zone size is treated as 0.

◆ layer()

LSurfaceLayer layer ( ) const
inlinenoexcept

Retrieves the layer to which the surface is assigned.

Whenever this value changes, the LSurface::layer() property is automatically updated, and the LSurface::layerChanged() event is triggered.

◆ exclusiveOutput()

LOutput* exclusiveOutput ( ) const
inlineoverridevirtual

Retrieves the current output.

This represents the output the surface is assigned to. It is initially set by the client at creation time and can be reassigned with setExclusiveOutput().

If not set initially, it means the client expects the compositor to set it.
The default implementation of configureRequest() sets it to the current LCursor::output() in such cases.

Returns
The output the surface is assigned to or nullptr.

Reimplemented from LBaseSurfaceRole.

◆ setExclusiveOutput()

void setExclusiveOutput ( LOutput output)
noexcept

Sets the current output.

LLayerRole surfaces can only be mapped when assigned to an initialized output.
If the assigned output is uninitialized, they become unmapped until it is initialized again.

Parameters
outputThe output to set as exclusive, or nullptr to remove it from all outputs/unmap it.

◆ scope()

const std::string& scope ( )
inlinenoexcept

Scope.

The scope is a client-defined string used for client identification, disambiguating order within the same layer, or other purposes.

◆ close()

void close ( )
noexcept

Requests the client to close the LLayerRole.