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

Class for handling drag & drop sessions. More...

+ Inheritance diagram for LDND:

Public Types

enum  Action : UInt32
 Action flags for drag & drop sessions. More...
 
- Public Types inherited from LFactoryObject
enum class  Type : Int32
 Base factory object types. More...
 

Public Member Functions

 LDND (const void *params) noexcept
 Constructor of the LDND class. More...
 
LDNDIconRoleicon () const noexcept
 Drag & drop session icon. More...
 
LSurfaceorigin () const noexcept
 Surface from which the drag & drop session originates. More...
 
LSurfacefocus () const noexcept
 Focused surface. More...
 
void setFocus (LSurface *surface, const LPointF &localPos) noexcept
 Set DND focus. More...
 
void sendMoveEvent (const LPointF &localPos, UInt32 ms) noexcept
 Send a DND move event. More...
 
const LEventtriggeringEvent () const noexcept
 Indicates which input event triggered the drag & drop session. More...
 
bool dragging () const noexcept
 Check if a drag & drop session is currently in progress. More...
 
void cancel () noexcept
 Cancels the session. More...
 
void drop () noexcept
 Drop the data offer. More...
 
Action preferredAction () const noexcept
 Preferred action of the compositor. More...
 
Action action () const noexcept
 Current action. More...
 
void setPreferredAction (Action action) noexcept
 Assigns the preferred action. 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...
 

Virtual Methods

virtual void startDragRequest ()
 Request to start a drag & drop session. More...
 
virtual void cancelled ()
 Notifies the cancellation of a session. More...
 
virtual void dropped ()
 Triggered after drop() More...
 

Additional Inherited Members

- 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

Class for handling drag & drop sessions.

The LDND class provides control over drag & drop sessions, and its unique instance can be accessed via LSeat::dnd().
Clients initiate a DND session by triggering startDragRequest(). Within that method, the compositor analyzes the triggeringEvent(), which could be, for example, a pointer button press on the origin() surface, and decides whether to accept the request or not. If the request is not accepted, the cancel() method should be called to end the session.

If the session continues, the compositor notifies clients when the dragged data is over their surfaces through the setFocus() and sendMoveEvent() methods, and finally notifies them when it's dropped with drop().
Clients usually create an LDNDIconRole (icon()) to be displayed behind the cursor or touch point.

Note
Louvre internally acts as middleware to coordinate the data exchange between clients.

During the session, clients can negotiate different actions such as Move or Copy .
The compositor can also set its preferred action with setPreferredAction().

Member Enumeration Documentation

◆ Action

enum Action : UInt32

Action flags for drag & drop sessions.

Clients who start drag & drop sessions or receive a data offer notify which actions they support.
For example, when dragging a file from a file manager window into another, the desired action might be to move or copy the file.
Louvre by default performs a match of actions supported by the source and destination client, giving preference to the first one listed in the enum, except for NoAction.
The compositor can also notify its preferred action using the setPreferredAction() method as exemplified in the default implementation of LKeyboard::keyEvent().

Enumerator
NoAction 

No preferred action.

Copy 

The preferred action is to copy.

Move 

The preferred action is to move.

Ask 

The destination client asks the source client the preferred action.

Constructor & Destructor Documentation

◆ LDND()

LDND ( const void *  params)
noexcept

Constructor of the LDND class.

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

Member Function Documentation

◆ icon()

LDNDIconRole * icon ( ) const
noexcept

Drag & drop session icon.

LDNDIconRole of the surface used as drag & drop icon.

Note
Not all drag & drop sessions use an icon.
Returns
nullptr if there is no session going on, or if the source client did not assign an icon.

◆ origin()

LSurface * origin ( ) const
noexcept

Surface from which the drag & drop session originates.

Returns
nullptr if there is no active session.

◆ focus()

LSurface * focus ( ) const
noexcept

Focused surface.

Surface to which the data offer is being presented to.

Returns
nullptr if there is no active session or if no surface has DND focus.

◆ setFocus()

void setFocus ( LSurface surface,
const LPointF localPos 
)
noexcept

Set DND focus.

Notifies the client that the dragged data is over one of their surfaces.

Note
If there is no active session, this is a no-op.
Parameters
surfaceThe surface to which the data is being offered, or nullptr to remove focus.
localPosThe local position within the surface where the drag point is located.

◆ sendMoveEvent()

void sendMoveEvent ( const LPointF localPos,
UInt32  ms 
)
noexcept

Send a DND move event.

Notifies the focused surface that the dragged point has moved.

Note
If no surface is focused, or there is no active session, this is a no-op.
Parameters
localPosThe local position within the surface where the drag point is located.
msThe millisecond timestamp of the move event.

◆ triggeringEvent()

const LEvent & triggeringEvent ( ) const
noexcept

Indicates which input event triggered the drag & drop session.

This should be used, for example, to detect if the dragged element should follow the pointer or a touch point.

Note
If the event was generated by an event like LKeyboardEnterEvent, the default implementation treats it as a pointer session.
Returns
The input event that triggered the drag & drop session.

◆ dragging()

bool dragging ( ) const
noexcept

Check if a drag & drop session is currently in progress.

Returns
true if there is an ongoing drag & drop session, false otherwise.

◆ cancel()

void cancel ( )
noexcept

Cancels the session.

Cancels the current drag & drop session.
If there is no session going on, calling this method is a no-op.

◆ drop()

void drop ( )
noexcept

Drop the data offer.

Drop the data offer on the surface with active focus and ends the session.
The destination client then exchanges the information with the source client, using the specified action.
If there is no focused surface, the session is cancelled.

◆ preferredAction()

LDND::Action preferredAction ( ) const
noexcept

Preferred action of the compositor.

Returns the preferred actions of the compositor set whith setPreferredAction().

◆ action()

LDND::Action action ( ) const
noexcept

Current action.

◆ setPreferredAction()

void setPreferredAction ( LDND::Action  action)
noexcept

Assigns the preferred action.

Assigns the compositor's preferred action for the session. Louvre by default assigns the Move action when holding down the Shift key and the Copy action when holding down the Ctrl key (check the default implementation of LKeyboard::keyEvent()).
If the specified action is not supported by the source and destination client, calling this method is a no-op.

◆ startDragRequest()

virtual void startDragRequest ( )
virtual

Request to start a drag & drop session.

Override this virtual method if you want to be notified when a client wants to start a drag & drop session.
This method is invoked only when there is no session in progress, which means only a single session can be active at a time.

Default implementation

{
if (sessionLockManager()->state() != LSessionLockManager::Unlocked && sessionLockManager()->client() != origin()->client())
{
cancel();
return;
}
// Left pointer button click
if (triggeringEvent().type() != LEvent::Type::Touch && origin()->hasPointerFocus() && seat()->pointer()->isButtonPressed(LPointerButtonEvent::Left))
{
if (icon())
icon()->surface()->setPos(cursor()->pos());
return;
}
// Touch down event
{
const LTouchDownEvent &touchDownEvent { (const LTouchDownEvent&)triggeringEvent() };
const LTouchPoint *tp { seat()->touch()->findTouchPoint(touchDownEvent.id()) };
if (tp && tp->surface() == origin())
{
if (icon())
icon()->surface()->setPos(LTouch::toGlobal(cursor()->output(), tp->pos()));
return;
}
}
cancel();
}
LSurface * surface() const noexcept
Returns the surface that has acquired the role provided in the constructor.
Definition: LBaseSurfaceRole.h:117
const LPointF & pos() const noexcept
Gets the current cursor position in compositor-global coordinates.
Definition: LCursor.h:56
void cancel() noexcept
Cancels the session.
Definition: LDND.cpp:144
LDNDIconRole * icon() const noexcept
Drag & drop session icon.
Definition: LDND.cpp:118
LSurface * origin() const noexcept
Surface from which the drag & drop session originates.
Definition: LDND.cpp:125
virtual void startDragRequest()
Request to start a drag & drop session.
const LEvent & triggeringEvent() const noexcept
Indicates which input event triggered the drag & drop session.
Definition: LDND.cpp:113
@ Touch
Touch event type.
@ Down
Down event subtype.
@ Left
Left button.
Definition: LPointerButtonEvent.h:25
void setDraggingSurface(LSurface *surface) noexcept
Keep track of the surface pressed by the main pointer button.
Definition: LPointer.cpp:339
LPointer * pointer() const noexcept
Access to pointer events.
Definition: LSeat.h:136
LTouch * touch() const noexcept
Access to touch events.
Definition: LSeat.h:156
@ Unlocked
Definition: LSessionLockManager.h:27
void setPos(const LPoint &newPos) noexcept
Assigns the position.
static LPointF toGlobal(LOutput *output, const LPointF &touchPointPos) noexcept
Transforms a touch point position to global coordinates.
Definition: LTouch.cpp:55
LTouchPoint * findTouchPoint(Int32 id) const noexcept
Gets the touch point that matches the specified id.
Definition: LTouch.cpp:46
LCursor * cursor() noexcept
Gets the compositor's cursor.
Definition: LCompositor.cpp:45
LSessionLockManager * sessionLockManager() noexcept
Gets the compositor's session lock manager.
Definition: LCompositor.cpp:50
LSeat * seat() noexcept
Gets the compositor's seat.
Definition: LCompositor.cpp:40

◆ cancelled()

virtual void cancelled ( )
virtual

Notifies the cancellation of a session.

Reimplement this virtual method if you want to be notified when a drag & drop session is cancelled.
The default implementation repaints outputs where the drag & drop icon was visible.

Default implementation

{
if (icon())
}
virtual void cancelled()
Notifies the cancellation of a session.
void repaintOutputs() noexcept
Repaints the intersected outputs.
Definition: LSurface.cpp:194

◆ dropped()

virtual void dropped ( )
virtual

Triggered after drop()

Default implementation

{
}
void useDefault() noexcept
Restores the default cursor.
Definition: LCursor.cpp:127
virtual void dropped()
Triggered after drop()