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

Group of input and output devices. More...

+ Inheritance diagram for LSeat:

Classes

struct  OutputConfiguration
 Configuration parameters for an output. More...
 

Public Member Functions

 LSeat (const void *params)
 Constructor of the LSeat class. More...
 
 ~LSeat ()
 Destructor of the LSeat class. More...
 
const std::vector< LGPU * > & gpus () const noexcept
 Retrieves the available GPUs. More...
 
const std::vector< LOutput * > & outputs () const noexcept
 Vector of available outputs. More...
 
const std::vector< LInputDevice * > & inputDevices () const noexcept
 Vector of available input devices. More...
 
const std::vector< LSurface * > & idleInhibitorSurfaces () const noexcept
 Surfaces requesting to inhibit the idle state. More...
 
const std::vector< const LIdleListener * > & idleListeners () const noexcept
 Listeners used by clients to detect when the user has been idle for a specified amount of time. More...
 
void setIsUserIdleHint (bool isIdle) noexcept
 Sets a hint about the user's idle state. More...
 
bool isUserIdleHint () const noexcept
 Hint about the user's idle state set with setIsUserIdleHint(). More...
 
const char * name () const noexcept
 The seat name. More...
 
LToplevelRoleactiveToplevel () const noexcept
 Active toplevel surface. More...
 
const std::vector< LToplevelResizeSession * > & toplevelResizeSessions () const noexcept
 Active LToplevelRole resize sessions. More...
 
const std::vector< LToplevelMoveSession * > & toplevelMoveSessions () const noexcept
 Active LToplevelRole move sessions. More...
 
LPointerpointer () const noexcept
 Access to pointer events. More...
 
LKeyboardkeyboard () const noexcept
 Access to keyboard events. More...
 
LTouchtouch () const noexcept
 Access to touch events. More...
 
LDNDdnd () const noexcept
 Access to the drag & drop session manager. More...
 
LClipboardclipboard () const noexcept
 Access to the clipboard manager. More...
 
void dismissPopups () noexcept
 Close all popups. More...
 
LPopupRoletopmostPopup () const noexcept
 Retrieve the topmost popup 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...
 

Session

void setTTY (UInt32 tty) noexcept
 Switches session. More...
 
Int32 openDevice (const char *path, Int32 *fd) noexcept
 Open a device. More...
 
Int32 closeDevice (Int32 id) noexcept
 Closes a device. More...
 
libseat * libseatHandle () const noexcept
 Libseat handle. More...
 
bool enabled () const noexcept
 Check the session state. More...
 

Virtual Methods

virtual void enabledChanged ()
 Notify a change in the enabled() property. More...
 
virtual void outputPlugged (LOutput *output)
 New available output. More...
 
virtual void outputUnplugged (LOutput *output)
 Disconnected output. More...
 
virtual void inputDevicePlugged (LInputDevice *device)
 New available input device. More...
 
virtual void inputDeviceUnplugged (LInputDevice *device)
 Disconnected input device. More...
 
virtual bool isIdleStateInhibited () const
 Checks if the idle state is inhibited. More...
 
virtual void onIdleListenerTimeout (const LIdleListener &listener)
 Notifies the timeout of an idle listener. More...
 
virtual void onEvent (const LEvent &event)
 Notifies of any input event. More...
 
virtual void nativeInputEvent (void *event)
 Native input backend events. More...
 
virtual bool configureOutputsRequest (LClient *client, const std::vector< OutputConfiguration > &configurations)
 Handles a client request to configure outputs. More...
 

Additional Inherited Members

- Public Types inherited from LFactoryObject
enum class  Type : Int32
 Base factory object types. 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...
 

Detailed Description

Group of input and output devices.

The LSeat class represents a collection of input and output devices such as a mouse, keyboard, touch screen, and displays (outputs). These devices are used within a session. Typically, for security reasons, access to these devices is restricted to a single process per session, often a Wayland compositor or X11 server.

To enable the libinput and DRM backends to manage devices without requiring superuser privileges, the openDevice() method is used to obtain device file descriptors. This method internally employs libseat.

By setting the environment variable LOUVRE_ENABLE_LIBSEAT to 0, libseat can be disabled, causing the compositor to launch without multi-session support. Consequently, certain features such as switching to another TTY may become unavailable.

Note
Disabling libseat may be necessary in scenarios where the compositor needs to be started remotely via SSH.

Class Documentation

◆ Louvre::LSeat::OutputConfiguration

struct Louvre::LSeat::OutputConfiguration

Configuration parameters for an output.

This structure is used in configureOutputsRequest().

Class Members
LOutput & output The output to be configured.
bool initialized Whether to enable or disable the output, see LCompositor::addOutput() and LCompositor::removeOutput().
const LOutputMode & mode The desired output mode to be applied, see LOutput::setMode().
LPoint pos The desired output position to be applied, see LOutput::setPos().
LTransform transform The desired output transform to be applied, see LOutput::setTransform().
Float32 scale The desired scale to be applied, see LOutput::setScale().

Constructor & Destructor Documentation

◆ LSeat()

LSeat ( const void *  params)

Constructor of the LSeat class.

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

◆ ~LSeat()

~LSeat ( )

Destructor of the LSeat class.

Invoked after LCompositor::onAnticipatedObjectDestruction().

Member Function Documentation

◆ gpus()

const std::vector< LGPU * > & gpus ( ) const
noexcept

Retrieves the available GPUs.

There is always at least one available GPU (even if virtual), and each output belongs to a single GPU.

◆ outputs()

const std::vector< LOutput * > & outputs ( ) const
noexcept

Vector of available outputs.

This method provides a vector of currently available outputs. The vector includes connected outputs that can be initialized as well as those that are already initialized.
To obtain only initialized outputs, refer to LCompositor::outputs().

◆ inputDevices()

const std::vector< LInputDevice * > & inputDevices ( ) const
noexcept

Vector of available input devices.

See also
inputDevicePlugged() and inputDeviceUnplugged().

◆ idleInhibitorSurfaces()

const std::vector< LSurface * > & idleInhibitorSurfaces ( ) const
noexcept

Surfaces requesting to inhibit the idle state.

See also
LIdleListener for more details.

◆ idleListeners()

const std::vector< const LIdleListener * > & idleListeners ( ) const
noexcept

Listeners used by clients to detect when the user has been idle for a specified amount of time.

See also
LIdleListener for more details.

◆ setIsUserIdleHint()

void setIsUserIdleHint ( bool  isIdle)
noexcept

Sets a hint about the user's idle state.

Resetting all idle listener timers manually with LIdleListeners::resetTimer() each time an event occurs isn't very CPU-friendly, as multiple events can be triggered in a single main loop iteration.

Instead, by using this method (which only updates a boolean variable), we can ask Louvre to update all timers only once at the end of a main loop iteration.

Note
The value is automatically set to true at the start of each iteration.
See also
LIdleListener for more details.

◆ isUserIdleHint()

bool isUserIdleHint ( ) const
noexcept

Hint about the user's idle state set with setIsUserIdleHint().

See also
LIdleListener for more details.
Returns
A boolean indicating the user's idle state. true if the user is idle, false otherwise.

◆ name()

const char * name ( ) const
noexcept

The seat name.

This method returns the name of the seat (E.g. "seat0").

◆ activeToplevel()

LToplevelRole * activeToplevel ( ) const
noexcept

Active toplevel surface.

This method returns the current LToplevelRole being configured with the LToplevelRole::State::Activated flag.
Only one toplevel surface can be active at a time, Louvre automatically deactivates other toplevels when one is activated.

Returns
The currently active LToplevelRole instance or nullptr if no toplevel is active.

◆ toplevelResizeSessions()

const std::vector< LToplevelResizeSession * > & toplevelResizeSessions ( ) const
noexcept

◆ toplevelMoveSessions()

const std::vector< LToplevelMoveSession * > & toplevelMoveSessions ( ) const
noexcept

◆ pointer()

LPointer* pointer ( ) const
inlinenoexcept

Access to pointer events.

Access to the LPointer instance used to receive pointer events from the backend and redirect them to clients.

◆ keyboard()

LKeyboard* keyboard ( ) const
inlinenoexcept

Access to keyboard events.

Access to the LKeyboard instance used to receive keyboard events from the backend and redirect them to clients.

◆ touch()

LTouch* touch ( ) const
inlinenoexcept

Access to touch events.

Access to the LTouch instance used to receive touch events from the backend and redirect them to clients.

◆ dnd()

LDND* dnd ( ) const
inlinenoexcept

Access to the drag & drop session manager.

◆ clipboard()

LClipboard* clipboard ( ) const
inlinenoexcept

Access to the clipboard manager.

◆ dismissPopups()

void dismissPopups ( )
noexcept

Close all popups.

This method closes all active LPopupRole surfaces in reverse order of creation.

See also
LPopupRole::dismiss()

◆ topmostPopup()

LPopupRole * topmostPopup ( ) const
noexcept

Retrieve the topmost popup role.

This method returns a pointer to the topmost popup.

Returns
A pointer to the topmost LPopupRole or nullptr if there is no popup.

◆ setTTY()

void setTTY ( UInt32  tty)
noexcept

Switches session.

This method allows you to switch to another session (TTY). Louvre also allows switching sessions using the shortcuts Ctrl + Alt + [F1, F2, ..., F10].

Parameters
ttyTTY number.

◆ openDevice()

Int32 openDevice ( const char *  path,
Int32 fd 
)
noexcept

Open a device.

Opens a device returning its ID and storing its file descriptor in fd.
The DRM and Libinput backends use this method to open GPUs and input devices respectively.

Parameters
pathLocation of the device (E.g. "/dev/dri/card0")
fdStores the file descriptor.
Returns
The ID of the device or -1 in case of an error.

◆ closeDevice()

Int32 closeDevice ( Int32  id)
noexcept

Closes a device.

This method is used by the input and graphic backends to close devices.

Parameters
idThe id of the device returned by openDevice().
Returns
0 if the device is closed successfully and -1 in case of error.

◆ libseatHandle()

libseat * libseatHandle ( ) const
noexcept

Libseat handle.

struct libseat handle.

Note
Returns nullptr if libseat is not being used.

◆ enabled()

bool enabled ( ) const
noexcept

Check the session state.

The session is considered disabled if the user is engaged in another active session (TTY).

Returns
true if the seat is active, false otherwise.

◆ enabledChanged()

virtual void enabledChanged ( )
virtual

Notify a change in the enabled() property.

Override this virtual method if you want to be notified when the seat is enabled or disabled.
The seat is enabled when the user is in the session (TTY) in which the compositor is running, and disabled when switching to a different session.

See also
setTTY()

Default implementation

{
if (!enabled())
return;
cursor()->setVisible(false);
cursor()->setVisible(true);
cursor()->move(1, 1);
}
void repaintAllOutputs() noexcept
Unlocks the rendering thread of all initialized outputs.
Definition: LCompositor.cpp:453
void setVisible(bool state) noexcept
Toggles the cursor visibility.
Definition: LCursor.cpp:271
void move(Float32 dx, Float32 dy) noexcept
Moves the cursor.
Definition: LCursor.cpp:212
bool enabled() const noexcept
Check the session state.
Definition: LSeat.cpp:180
virtual void enabledChanged()
Notify a change in the enabled() property.
LCursor * cursor() noexcept
Gets the compositor's cursor.
Definition: LCompositor.cpp:47
LCompositor * compositor() noexcept
Gets the static LCompositor instance.
Definition: LCompositor.cpp:37

◆ outputPlugged()

virtual void outputPlugged ( LOutput output)
virtual

New available output.

This event is invoked by the graphic backend when a new output is available, for example when connecting an external monitor through an HDMI port.
The default implementation initializes the new output and positions it at the end (right) of the already initialized outputs.

Default Implementation

void LSeat::outputPlugged(LOutput *output)
{
// Probably a VR headset, meant to be leased by clients
if (output->isNonDesktop())
{
output->setLeasable(true);
return;
}
output->setScale(output->dpi() >= 200 ? 2 : 1);
if (compositor()->outputs().empty())
output->setPos(0);
else
output->setPos(compositor()->outputs().back()->pos() + LPoint(compositor()->outputs().back()->size().w(), 0));
compositor()->addOutput(output);
}
bool addOutput(LOutput *output)
Initializes the specified output.
Definition: LCompositor.cpp:459
const std::vector< LOutput * > & outputs() const noexcept
Vector of available outputs.
Definition: LSeat.cpp:68
virtual void outputPlugged(LOutput *output)
New available output.
LPointTemplate< Int32 > LPoint
2D vector of 32 bits integers
Definition: LNamespaces.h:250

◆ outputUnplugged()

virtual void outputUnplugged ( LOutput output)
virtual

Disconnected output.

This event is invoked by the graphic backend when an output is no longer available, for example when an external monitor connected to an HDMI port is disconnected.

The default implementation removes the output from the compositor and re-arranges the ones already initialized.

Note
Louvre automatically employs LCompositor::removeOutput() after this event, so calling it directly is not mandatory.

Default Implementation

void LSeat::outputUnplugged(LOutput *output)
{
Int32 totalWidth { 0 };
for (LOutput *o : compositor()->outputs())
{
o->setPos(LPoint(totalWidth, 0));
totalWidth += o->size().w();
}
}
void removeOutput(LOutput *output)
Uninitializes the specified output.
Definition: LCompositor.cpp:491
virtual void outputUnplugged(LOutput *output)
Disconnected output.
int32_t Int32
32 bits signed integer
Definition: LNamespaces.h:217

◆ inputDevicePlugged()

virtual void inputDevicePlugged ( LInputDevice device)
virtual

New available input device.

Default Implementation

void LSeat::inputDevicePlugged(LInputDevice *device)
{
L_UNUSED(device);
}
virtual void inputDevicePlugged(LInputDevice *device)
New available input device.

◆ inputDeviceUnplugged()

virtual void inputDeviceUnplugged ( LInputDevice device)
virtual

Disconnected input device.

Default Implementation

void LSeat::inputDeviceUnplugged(LInputDevice *device)
{
L_UNUSED(device);
}
virtual void inputDeviceUnplugged(LInputDevice *device)
Disconnected input device.

◆ isIdleStateInhibited()

virtual bool isIdleStateInhibited ( ) const
virtual

Checks if the idle state is inhibited.

The default implementation returns true if at least one of the surfaces listed in idleInhibitorSurfaces() is mapped and visible on at least one output.

Note
Since the way of displaying surfaces is specific to each compositor, no additional checks are performed to determine if the surface is obscured by opaque areas. You may override this method to include such checks if needed.
See also
LIdleListener for more details.
Returns
Returns true if the idle state is inhibited, false otherwise.

Default Implementation

{
for (LSurface *surface : idleInhibitorSurfaces())
if (surface->mapped() && !surface->outputs().empty())
return true;
return false;
}
const std::vector< LSurface * > & idleInhibitorSurfaces() const noexcept
Surfaces requesting to inhibit the idle state.
Definition: LSeat.cpp:78
virtual bool isIdleStateInhibited() const
Checks if the idle state is inhibited.

◆ onIdleListenerTimeout()

virtual void onIdleListenerTimeout ( const LIdleListener listener)
virtual

Notifies the timeout of an idle listener.

If LIdleListener::resetTimer() is not called within this event, the LIdleListener::client() will be notified that the user is idle until LIdleListener::resetTimer() is called again.

If the idle state is being inhibited (see isIdleStateInhibited()) LIdleListener::resetTimer() should always be called.

See also
LIdleListener for more details.

Default Implementation

void LSeat::onIdleListenerTimeout(const LIdleListener &listener)
{
listener.resetTimer();
/* If the timer is not reset, the client will assume the user is idle. */
}
virtual void onIdleListenerTimeout(const LIdleListener &listener)
Notifies the timeout of an idle listener.

◆ onEvent()

virtual void onEvent ( const LEvent event)
virtual

Notifies of any input event.

This event is similar to nativeInputEvent(), but is only invoked for input event types currently supported by Louvre.

Default Implementation

void LSeat::onEvent(const LEvent &event)
{
L_UNUSED(event)
/*
* for (const LIdleListener *idleListener : idleListeners())
* idleListener->resetTimer();
*
* Resetting all timers each time an event occurs is not CPU-friendly,
* as multiple events can be triggered in a single main loop iteration.
* Instead, using the option below (setIsUserIdleHint()) is more efficient.
*/
/*
* Setting this flag to false indicates the user wasn't idle during
* this main loop iteration. If that's the case, Louvre will reset
* all timers only once at the end of the iteration.
* The flag is automatically set to true again afterwards.
*/
}
virtual void onEvent(const LEvent &event)
Notifies of any input event.
void setIsUserIdleHint(bool isIdle) noexcept
Sets a hint about the user's idle state.
Definition: LSeat.cpp:88

◆ nativeInputEvent()

virtual void nativeInputEvent ( void *  event)
virtual

Native input backend events.

Override this virtual method if you want to access all events generated by the input backend.

Parameters
eventOpaque handle to the native backend event. When using the Libinput backend it corresponds to a libinput_event struct
Note
Use LCompositor::inputBackendId() to determine which input backend is in use.

Default implementation

void LSeat::nativeInputEvent(void *event)
{
L_UNUSED(event);
}
virtual void nativeInputEvent(void *event)
Native input backend events.

◆ configureOutputsRequest()

virtual bool configureOutputsRequest ( LClient client,
const std::vector< OutputConfiguration > &  configurations 
)
virtual

Handles a client request to configure outputs.

Triggered by clients using the wlr-output-management protocol, such as wdisplays, wlr-randr, and wayland-displays.

The configurations vector contains all parameters the client intends to configure all available outputs with, including uninitialized ones (see outputs()).

The compositor can ignore the provided parameters and configure the outputs differently (e.g., to prevent overlapping). Returning true notifies the client that the configurations were fully or partially applied. Returning false indicates that the configurations failed to apply, and Louvre will revert all output parameters to their previous state.

Parameters
clientThe client issuing the request.
configurationsParameters to configure each available output.
Returns
true if the configurations were completely or partially applied, or false to revert changes.

Default implementation

bool LSeat::configureOutputsRequest(LClient *client, const std::vector<OutputConfiguration> &configurations)
{
// All requests accepted by default (unsafe) see LCompositor::globalsFilter().
L_UNUSED(client)
for (const auto &conf : configurations)
{
conf.output.setPos(conf.pos);
conf.output.setTransform(conf.transform);
conf.output.setScale(conf.scale);
conf.output.setMode(&conf.mode);
if (conf.initialized)
compositor()->addOutput(&conf.output);
else
compositor()->removeOutput(&conf.output);
}
// Revert changes if the configuration results in zero initialized outputs
return !compositor()->outputs().empty();
}
const std::vector< LOutput * > & outputs() const noexcept
Gets a vector of all initialized outputs.
Definition: LCompositor.cpp:582
virtual bool configureOutputsRequest(LClient *client, const std::vector< OutputConfiguration > &configurations)
Handles a client request to configure outputs.