XMDRAGCONTEXT(3)

πŸ“¦
version 2.5.2 Β· 2 versions
, in alpine 3.24, arch rolling, centos-stream 9, epel 10, fedora 43, fedora 44, nixos 26.05, nixpkgs unstable, opensuse-leap 16.0

πŸ’– NAME πŸ’–

XmDragContext β€” The DragContext widget class, no cap. πŸ’…


✨ SYNOPSIS ✨

#include <Xm/DragDrop.h>

🌸 DESCRIPTION 🌸

Okay so bestie, DragContexts are these special widgets used in drag and drop transactions. πŸ¦‹ A DragContext is implemented as a widget, but here's the tea: a client does not explicitly create a DragContext widget. Instead, a client initiates a drag and drop transaction by calling XmDragStart, and this routine initializes and returns a DragContext widget. There is a unique DragContext for each drag operation. The toolkit frees a DragContext when a transaction is complete; therefore, an application programmer should not explicitly destroy a DragContext. Like, don't even think about it. πŸ’€

Initiator and receiver clients both use DragContexts to track the state of a transaction. When the initiator and receiver of a transaction are in the same client, they share the same DragContext instance. If they are in different clients, there are two separate DragContexts. In this case, the initiator calls XmDragStart and the toolkit provides a DragContext for the receiver client. The only resources pertinent to the receiver are XmNexportTargets and XmNnumExportTargets. These can both be passed as arguments to the XmDropSiteRetrieve function to obtain information about the current drop site. Slay. ✨

In general, in order to receive data, a drop site must share at least one target type and operation in common with a drag source. The DragContext resource, XmNexportTargets, identifies the selection targets for the drag source. These export targets are compared with the XmNimportTargets resource list specified by a drop site. The DragContext resource, XmNdragOperations, identifies the valid operations that can be applied to the source data by the initiator. The drop site counterpart resource is XmNdropSiteOperations, which indicates a drop site's supported operations. Vibe check: they gotta match. πŸ’…

A client uses DragIcon widgets to define the drag-over animation effects associated with a given drag and drop transaction. An initiator specifies a set of drag icons, selects a blending model, and sets foreground and background cursor colors with DragContext resources. It's giving aesthetic. πŸŽ€

The type of drag-over visual used to represent a drag operation depends on the drag protocol style. In preregister mode, the server is grabbed, and either a cursor or a pixmap may be used as a drag-over visual. In dynamic mode, drag-over visuals must be implemented with the X cursor. If the resulting drag protocol style is Drop Only or None and the XmNdragInitiatorProtocolStyle is XmDRAG_DYNAMIC or XmDRAG_PREFER_DYNAMIC, then a dynamic visual style (cursor) is used. Otherwise, a preregister visual style is used. Iconic. πŸ‘‘


πŸ‘‘ Classes πŸ‘‘

DragContext inherits behavior and resources from Core.

The class pointer is xmDragContextClass.

The class name is XmDragContext.


🧚 New Resources 🧚

The following table defines a set of widget resources used by the programmer to specify data. The programmer can also set the resource values for the inherited classes to set attributes for this widget. To reference a resource by name or by class in a .Xdefaults file, remove the XmN or XmC prefix and use the remaining letters. To specify one of the defined values for a resource in a .Xdefaults file, remove the Xm prefix and use the remaining letters (in either lowercase or uppercase, but include any underscores between words). The codes in the access column indicate if the given resource can be set at creation time (C), set by using XtSetValues (S), retrieved by using XtGetValues (G), or is not applicable (N/A).

okay bestie, so every single one of these has the same five lil facts attached to it: the resource name, its class, its type, its default, and its access code. Read them like a little recipe card πŸ’…

  • XmNblendModel β€” class: XmCBlendModel Β· type: unsigned char Β· default: XmBLEND_ALL Β· access: CG
  • XmNclientData β€” class: XmCClientData Β· type: XtPointer Β· default: NULL Β· access: CSG
  • XmNconvertProc β€” class: XmCConvertProc Β· type: XtConvertSelectionIncrProc Β· default: NULL Β· access: CSG
  • XmNcursorBackground β€” class: XmCCursorBackground Β· type: Pixel Β· default: dynamic Β· access: CSG
  • XmNcursorForeground β€” class: XmCCursorForeground Β· type: Pixel Β· default: dynamic Β· access: CSG
  • XmNdragDropFinishCallback β€” class: XmCCallback Β· type: XtCallbackList Β· default: NULL Β· access: CSG
  • XmNdragMotionCallback β€” class: XmCCallback Β· type: XtCallbackList Β· default: NULL Β· access: C
  • XmNdragOperations β€” class: XmCDragOperations Β· type: unsigned char Β· default: XmDROP_COPY | XmDROP_MOVE Β· access: C
  • XmNdropFinishCallback β€” class: XmCCallback Β· type: XtCallbackList Β· default: NULL Β· access: C
  • XmNdropSiteEnterCallback β€” class: XmCCallback Β· type: XtCallbackList Β· default: NULL Β· access: C
  • XmNdropSiteLeaveCallback β€” class: XmCCallback Β· type: XtCallbackList Β· default: NULL Β· access: C
  • XmNdropStartCallback β€” class: XmCCallback Β· type: XtCallbackList Β· default: NULL Β· access: C
  • XmNexportTargets β€” class: XmCExportTargets Β· type: Atom * Β· default: NULL Β· access: CSG
  • XmNincremental β€” class: XmCIncremental Β· type: Boolean Β· default: False Β· access: CSG
  • XmNinvalidCursorForeground β€” class: XmCCursorForeground Β· type: Pixel Β· default: dynamic Β· access: CSG
  • XmNnoneCursorForeground β€” class: XmCCursorForeground Β· type: Pixel Β· default: dynamic Β· access: CSG
  • XmNnumExportTargets β€” class: XmCNumExportTargets Β· type: Cardinal Β· default: 0 Β· access: CSG
  • XmNoperationChangedCallback β€” class: XmCCallback Β· type: XtCallbackList Β· default: NULL Β· access: C
  • XmNoperationCursorIcon β€” class: XmCOperationCursorIcon Β· type: Widget Β· default: dynamic Β· access: CSG
  • XmNsourceCursorIcon β€” class: XmCSourceCursorIcon Β· type: Widget Β· default: dynamic Β· access: CSG
  • XmNsourcePixmapIcon β€” class: XmCSourcePixmapIcon Β· type: Widget Β· default: dynamic Β· access: CSG

quick vibe check on the deets ✨

  • the XmCCallback girlies are all XtCallbackList type, defaulting to NULL, and there's a whole little clique of them: XmNdragDropFinishCallback, XmNdragMotionCallback, XmNdropFinishCallback, XmNdropSiteEnterCallback, XmNdropSiteLeaveCallback, XmNdropStartCallback, XmNoperationChangedCallback 🫢
  • the icon trio β€” XmNoperationCursorIcon, XmNsourceCursorIcon, XmNsourcePixmapIcon β€” are all Widget typed with dynamic defaults, lowkey iconic πŸ’…
  • dynamic defaults show up a lot: XmNcursorBackground, XmNcursorForeground, XmNinvalidCursorForeground, XmNnoneCursorForeground, plus the icons and XmNoperationCursorIcon πŸ¦‹
  • watch the access codes fr fr, they're not all the same: some are CSG and some are just C β€” no cap, they differ per resource πŸ‘‘
not me pointing out that XmNinvalidCursorForeground and XmNnoneCursorForeground share the class XmCCursorForeground with XmNcursorForeground β€” same class, three different names, it's giving family reunion 😭
  • XmNstateCursorIcon β€” class XmCStateCursorIcon, type Widget, default dynamic, access CSG
  • XmNtopLevelEnterCallback β€” class XmCCallback, type XtCallbackList, default NULL, access C
  • XmNtopLevelLeaveCallback β€” class XmCCallback, type XtCallbackList, default NULL, access C
  • XmNvalidCursorForeground β€” class XmCCursorForeground, type Pixel, default dynamic, access CSG

XmNblendModel

okay bestie this one decides which combo of DragIcons get blended together to make that drag-over visual you see while you're dragging. it's giving "choose your fighter":

  • XmBLEND_ALL β€” blends all three DragIcons: the source, state and operation icons. they're layered top to bottom with the operation icon on top and the source icon on the bottom. the hotspot is derived from the state icon. πŸ’…
  • XmBLEND_STATE_SOURCE β€” blends the state and source icons only. the hotspot is derived from the state icon.
  • XmBLEND_JUST_SOURCE β€” specifies that only the source icon is used, which the initiator updates as required.
  • XmBLEND_NONE β€” specifies that no drag-over visual is generated. the client tracks the drop site status through callback routines and updates the drag-over visuals as necessary.

XmNclientData

Specifies the client data to be passed to XmNconvertProc when it is invoked.

XmNconvertProc

If XmNincremental is True, specifies a procedure of type XtConvertSelectionIncrProc that converts the source data to the format(s) requested by the receiver client. the widget argument passed to this procedure is the DragContext widget. the selection atom passed is _MOTIF_DROP. if XmNincremental is False, the procedure is an XtConvertSelectionProc, and should ignore the max_length, client_data, and request_id arguments and should handle the conversion atomically. data returned by XmNconvertProc must be allocated using XtMalloc, and will be freed automatically by the toolkit after the transfer. for additional info on selection conversion procedures, see X Toolkit Intrinsicsβ€”C Language Interface. 🫢

XmNcursorBackground

Specifies the background pixel value of the cursor.

XmNcursorForeground

Specifies the foreground pixel value of the cursor when the state icon is not blended. this resource defaults to the foreground color of the widget passed to the XmDragStart function.

XmNdragDropFinishCallback

Specifies the list of callbacks that are called when the transaction is completed. the type of the structure whose address is passed to this callback is XmDragDropFinishCallbackStruct. the reason sent by the callback is XmCR_DRAG_DROP_FINISH.

XmNdragMotionCallback

Specifies the list of callbacks that are invoked when the pointer moves. the type of structure whose address is passed to this callback is XmDragMotionCallbackStruct. the reason sent by the callback is XmCR_DRAG_MOTION.

XmNdragOperations

Specifies the set of valid operations associated with an initiator client for a drag transaction. this resource is a bit mask that is formed by combining one or more of the following values using a bitwise operation such as inclusive OR (|):

  • XmDROP_COPY
  • XmDROP_LINK
  • XmDROP_MOVE

The value XmDROP_NOOP for this resource indicates that no operations are valid. for Text and TextField widgets, this resource is set to XmDROP_COPY | XmDROP_MOVE; for List widgets, it is set to XmDROP_COPY. ✨

XmNdropFinishCallback

Specifies the list of callbacks that are invoked when the drop is completed. the type of the structure whose address is passed to this callback is XmDropFinishCallbackStruct. the reason sent by the callback is XmCR_DROP_FINISH.

XmNdropSiteEnterCallback

Specifies the list of callbacks that are invoked when the pointer enters a drop site. the type of the structure whose address is passed to this callback is XmDropSiteEnterCallbackStruct. the reason sent by the callback is XmCR_DROP_SITE_ENTER.

XmNdropSiteLeaveCallback

Specifies the list of callbacks that are invoked when the pointer leaves a drop site. the type of the structure whose address is passed to this callback is XmDropSiteLeaveCallbackStruct. the reason sent by the callback is XmCR_DROP_SITE_LEAVE.

XmNdropStartCallback

Specifies the list of callbacks that are invoked when a drop is initiated. the type of the structure whose address is passed to this callback is XmDropStartCallbackStruct. the reason sent by the callback is XmCR_DROP_START.

XmNexportTargets

Specifies the list of target atoms associated with this source. this resource identifies the selection targets this source can be converted to.

XmNincremental

Specifies a Boolean value that indicates whether the transfer on the initiator side uses the Xt incremental selection transfer mechanism described in X Toolkit Intrinsicsβ€”C Language Interface. if the value is True, the initiator uses incremental transfer; if the value is False, the initiator uses atomic transfer. πŸ¦‹

XmNinvalidCursorForeground

Specifies the foreground pixel value of the cursor when the state is invalid. this resource defaults to the value of the XmNcursorForeground resource.

XmNnoneCursorForeground

Specifies the foreground pixel value of the cursor when the state is none. this resource defaults to the value of the XmNcursorForeground resource.

XmNnumExportTargets

Specifies the number of entries in the list of export targets.

XmNoperationChangedCallback

Specifies the list of callbacks that are invoked when the drag is started and when the user requests that a different operation be applied to the drop. the type of the structure whose address is passed to this callback is XmOperationChangedCallbackStruct. the reason sent by the callback is XmCR_OPERATION_CHANGED.

XmNoperationCursorIcon

Specifies the cursor icon used to designate the type of operation performed by the drag transaction. if NULL, XmScreen resources provide default icons for copy, link, and move operations.

XmNsourceCursorIcon

Specifies the cursor icon used to represent the source when a dynamic visual style is used. if NULL, the XmNdefaultSourceCursorIcon resource of XmScreen provides a default cursor icon.

XmNsourcePixmapIcon

Specifies the pixmap icon used to represent the source when a preregister visual style is used. the icon is used in conjunction with the colormap of the widget passed to XmDragStart. if NULL, XmNsourceCursorIcon is used.

XmNstateCursorIcon

Specifies the cursor icon used to designate the state of a drop site. if NULL, XmScreen resources provide default icons for a valid, invalid, and no drop site condition. πŸ’œ

XmNtopLevelEnterCallback

Specifies the list of callbacks that are called when the pointer enters a top-level window or root window (due to changing screens). the type of the structure whose address is passed to this callback is XmTopLevelEnterCallbackStruct. the reason sent by the callback is XmCR_TOP_LEVEL_ENTER.

XmNtopLevelLeaveCallback

Specifies the list of callbacks that are called when the pointer leaves a top level window or the root window (due to changing screens). the type of the structure whose address is passed to this callback is XmTopLevelLeaveCallbackStruct. the reason sent by the callback is XmCR_TOP_LEVEL_LEAVE.

XmNvalidCursorForeground

Specifies the foreground pixel value of the cursor designated as a valid cursor icon.


🌈 Inherited Resources 🌈

DragContext inherits behavior and resources from the superclass described in the following table. for a complete description of each resource, refer to the Core reference page. πŸ‘‘

πŸŽ€ Core Resource Set πŸŽ€

okay bestie, here's the whole core resource lineup πŸ’– every single one of these has a Name, a Class, a Type, a Default, and an Access code, and we are NOT skipping a single one, fr fr:

  • XmNaccelerators β€” class XmCAccelerators, type XtAccelerators, default dynamic, access CSG ✨
  • XmNancestorSensitive β€” class XmCSensitive, type Boolean, default dynamic, access G πŸ’…
  • XmNbackground β€” class XmCBackground, type Pixel, default dynamic, access CSG πŸŽ€
  • XmNbackgroundPixmap β€” class XmCPixmap, type Pixmap, default XmUNSPECIFIED_PIXMAP, access CSG πŸ¦‹
  • XmNborderColor β€” class XmCBorderColor, type Pixel, default XtDefaultForeground, access CSG 🌸
  • XmNborderPixmap β€” class XmCPixmap, type Pixmap, default XmUNSPECIFIED_PIXMAP, access CSG ✨
  • XmNborderWidth β€” class XmCBorderWidth, type Dimension, default 0, access CSG πŸ’œ
  • XmNcolormap β€” class XmCColormap, type Colormap, default dynamic, access CG 🌈
  • XmNdepth β€” class XmCDepth, type int, default dynamic, access CG πŸ”₯
  • XmNdestroyCallback β€” class XmCCallback, type XtCallbackList, default NULL, access C 😭
  • XmNheight β€” class XmCHeight, type Dimension, default dynamic, access CSG πŸŽ€
  • XmNinitialResourcesPersistent β€” class XmCInitialResourcesPersistent, type Boolean, default True, access C ⭐
  • XmNmappedWhenManaged β€” class XmCMappedWhenManaged, type Boolean, default True, access CSG πŸ‘‘
  • XmNscreen β€” class XmCScreen, type Screen *, default dynamic, access CG πŸ’–
  • XmNsensitive β€” class XmCSensitive, type Boolean, default True, access CSG πŸ“
  • XmNtranslations β€” class XmCTranslations, type XtTranslations, default dynamic, access CSG 🧚
  • XmNwidth β€” class XmCWidth, type Dimension, default dynamic, access CSG 🌸
  • XmNx β€” class XmCPosition, type Position, default 0, access CSG ✨
  • XmNy β€” class XmCPosition, type Position, default 0, access CSG πŸ¦‹

πŸ’… Callback Information πŸ’…

so every single DragContext callback comes with its own little callback structure, like a lil bestie that shows up with the receipts 🫢

A pointer to the following structure is passed to the XmNdragDropFinishCallback callback:

typedef struct
{
        int reason;
        XEvent  *event;
        Time timeStamp;
}XmDragDropFinishCallbackStruct, *XmDragDropFinishCallback;
  • reason β€” Indicates why the callback was invoked πŸ‘€
  • event β€” Points to the XEvent that triggered the callback ⚑
  • timeStamp β€” Specifies the time at which either the drag or the drop was completed ⏰

A pointer to the following structure is passed to callbacks for XmNdragMotionCallback:

typedef struct
{
        int reason;
        XEvent *event;
        Time timeStamp;
        unsigned char operation;
        unsigned char operations;
        unsigned char dropSiteStatus;
        Position x;
        Position y;
}XmDragMotionCallbackStruct, *XmDragMotionCallback;
  • reason β€” Indicates why the callback was invoked πŸ’…
  • event β€” Points to the XEvent that triggered the callback 🌟
  • timeStamp β€” Specifies the timestamp of the logical event ⏱️
  • operation β€” Identifies an operation πŸ‘‘

okay so if the toolkit just called a DropSite's XmNdragProc, bestie, it sets operation to whatever the operation member of the XmDragProcCallbackStruct was holding the second that XmNdragProc handed control back. πŸ’…

But if the toolkit hasn't called an XmNdragProc, and your pointer is chillin' inside an active drop site? Then it picks operation by doing a bitwise AND of the initial operations value and the DropSite's XmNdropSiteOperations resource. It scans that set like: XmDROP_MOVE first, then XmDROP_COPY, then XmDROP_LINK β€” and locks in the first one it finds. If none of those three show up? It's giving XmDROP_NOOP, periodt. πŸ™ˆ

And if the toolkit hasn't called an XmNdragProc and the pointer isn't inside any active drop site? Then it picks operation from the initial value of the operations member itself. Same drill: XmDROP_MOVE first, then XmDROP_COPY, then XmDROP_LINK, first match wins. Nothing found? XmDROP_NOOP again. πŸ’€

  • operations β€” tells you the set of operations supported for the source data. ✨
    • If the toolkit just called a DropSite's XmNdragProc, it sets operations to the bitwise AND of the DropSite's XmNdropOperations and the operations member of the XmDragProcCallbackStruct at the moment XmNdragProc returns. If that resulting set is empty, operations becomes XmDROP_NOOP.
    • If the toolkit hasn't called an XmNdragProc and the user didn't select an operation (by pressing a modifier key), operations gets set to the value of the DragContext's XmNdragOperations resource.
    • If the toolkit hasn't called an XmNdragProc and the user did select an operation, operations becomes the bitwise AND of that corresponding operation and the DragContext's XmNdragOperations resource. Empty set? XmDROP_NOOP, no cap. 🫢
  • dropSiteStatus β€” says whether a drop site is valid or not. 🌸
    • If the toolkit just called a DropSite's XmNdragProc, dropSiteStatus gets the value of the dropSiteStatus member of the XmDragProcCallbackStruct at the time XmNdragProc returns.
    • If the toolkit hasn't called an XmNdragProc, it initializes dropSiteStatus like this: it's XmNO_DROP_SITE if the pointer is over an inactive drop site, or just not over a drop site at all.
    • The toolkit sets dropSiteStatus to XmDROP_SITE_VALID only if all these conditions are met:
      • The pointer is over an active drop site. πŸ‘‘
      • The DragContext's XmNexportTargets and the DropSite's XmNimportTargets are compatible. πŸ¦‹
      • The initial value of the operation member is not XmDROP_NOOP.
    • Otherwise, dropSiteStatus becomes XmDROP_SITE_INVALID. 😭

A pointer to this next structure gets passed for the XmNdropFinishCallback callback:

typedef struct
{
        int reason;
        XEvent *event;
        Time timeStamp;
        unsigned char operation;
        unsigned char operations;
        unsigned char dropSiteStatus;
        unsigned char dropAction;
        unsigned char completionStatus;
}XmDropFinishCallbackStruct, *XmDropFinishCallback;
  • reason β€” tells you why the callback got invoked. πŸ’…
  • event β€” points to the XEvent that triggered the callback. ✨
  • timeStamp β€” specifies the time at which the drop was completed. ⭐
  • operation β€” identifies an operation. πŸŽ€
    • If the pointer is over an active drop site when the drop begins, the toolkit sets operation to the value of the operation member of the XmDropProcCallbackStruct at the time the DropSite's XmNdropProc returns.
    • If the pointer is not over an active drop site when the drop begins, the toolkit picks operation from the initial value of the operations member. It searches that set for XmDROP_MOVE first, then XmDROP_COPY, then XmDROP_LINK, and sets operation to the first one it finds. Finds none of them? operation becomes XmDROP_NOOP. πŸ’€
  • operations β€” the set of operations supported for the source data. 🌈
    • If the pointer is over an active drop site when the drop begins, operations becomes the bitwise AND of the DropSite's XmNdropOperations and the value of the operations member of the XmDropProcCallbackStruct at the time the DropSite's XmNdropProc returns. Empty set? XmDROP_NOOP.
    • If the pointer is not over an active drop site when the drop begins, and the user didn't select an operation (by pressing a modifier key), operations becomes the value of the DragContext's XmNdragOperations resource.
    • If the pointer is not over an active drop site when the drop begins, and the user did select an operation, operations becomes the bitwise AND of the corresponding operation and the value of the DragContext's XmNdragOperations resource. Empty set? XmDROP_NOOP. πŸ™ˆ
  • dropSiteStatus β€” whether a drop site is valid or not. 🫢
    • If the pointer is over an active drop site when the drop begins, dropSiteStatus gets the value of the dropSiteStatus member of the XmDropProcCallbackStruct at the time the DropSite's XmNdropProc returns.
    • If the pointer is not over an active drop site when the drop begins, dropSiteStatus becomes XmNO_DROP_SITE.
  • dropAction β€” identifies the drop action. The values are XmDROP, XmDROP_CANCEL, XmDROP_HELP, and XmDROP_INTERRUPT. Heads up bestie, XmDROP_INTERRUPT is currently unsupported β€” if you specify it, it gets interpreted as an XmDROP_CANCEL. 😭
  • completionStatus β€” an IN/OUT member that indicates the status of the drop action. After the last callback procedure has returned, the final value of this member determines what visual transition effects get applied. There are two values:
    • XmDROP_SUCCESS β€” the drop was successful. πŸŽ‰
    • XmDROP_FAILURE β€” the drop was unsuccessful. πŸ’€

A pointer to this next structure gets passed to callbacks for XmNdropSiteEnterCallback:

typedef struct
{
        int reason;
        XEvent *event;
        Time timeStamp;
        unsigned char operation;
        unsigned char operations;
        unsigned char dropSiteStatus;
        Position x;
        Position y;
}XmDropSiteEnterCallbackStruct, *XmDropSiteEnterCallback;
  • reason β€” tells you why the callback got invoked. πŸ’–
  • event β€” points to the XEvent that triggered the callback. ✨
  • timeStamp β€” specifies the time the crossing event occurred. ⏰
  • operation β€” identifies an operation. πŸ’…
    • If the toolkit just called a DropSite's XmNdragProc, operation gets the value of the operation member of the XmDragProcCallbackStruct at the time XmNdragProc returns.
    • If the toolkit hasn't called an XmNdragProc, it picks operation from the bitwise AND of the initial value of the operations member and the value of the DropSite's XmNdropSiteOperations resource. It searches that set for XmDROP_MOVE first, then XmDROP_COPY, then XmDROP_LINK, and sets operation to the first one it finds. If it finds none of these in the set, operation becomes XmDROP_NOOP. 😭
  • operations β€” the set of operations supported for the source data. 🌸
    • If the toolkit just called a DropSite's XmNdragProc, operations becomes the bitwise AND of the DropSite's XmNdropOperations and the value of the operations member of the XmDragProcCallbackStruct at the time XmNdragProc returns. Empty set? XmDROP_NOOP.
    • If the toolkit hasn't called an XmNdragProc and the user didn't select an operation (by pressing a modifier key), operations becomes the value of the DragContext's XmNdragOperations resource.
    • If the toolkit hasn't called an XmNdragProc and the user did select an operation, operations becomes the bitwise AND of the corresponding operation and the value of the DragContext's XmNdragOperations resource. Empty set? XmDROP_NOOP, fr fr. 🫢
  • dropSiteStatus β€” whether a drop site is valid or not. 🌈
    • If the toolkit just called a DropSite's XmNdragProc, dropSiteStatus gets the value of the dropSiteStatus member of the XmDragProcCallbackStruct at the time XmNdragProc returns.
  • dropSiteStatus β€” the whole "is this drop site valid" tea β˜•οΈ. If the toolkit has not called XmNdragProc, it initializes dropSiteStatus to XmDROP_SITE_VALID when the DragContext's XmNexportTargets and the DropSite's XmNimportTargets are compatible and the initial value of the operation member is not XmDROP_NOOP. Otherwise? Toolkit sets dropSiteStatus to XmDROP_SITE_INVALID. That's it, that's the rule πŸ’…
  • x β€” the x-coordinate of the pointer, in root window coordinates. Yes bestie, root window coordinates, not local, don't get it twisted.
  • y β€” the y-coordinate of the pointer, in root window coordinates. Same deal 🫢

A pointer to this structure gets passed to the callbacks for XmNdropSiteLeaveCallback:

typedef struct
{
        int reason;
        XEvent *event;
        Time timeStamp;
}XmDropSiteLeaveCallbackStruct, *XmDropSiteLeaveCallback;
  • reason β€” why the callback got invoked in the first place.
  • event β€” points at the XEvent that triggered the callback.
  • timeStamp β€” the timestamp of the logical event. logical, okay?*

A pointer to this next structure is passed for the XmNdropStartCallback callback:

typedef struct
{
        int reason;
        XEvent *event;
        Time timeStamp;
        unsigned char operation;
        unsigned char operations;
        unsigned char dropSiteStatus;
        unsigned char dropAction;
        Position x;
        Position y;
}XmDropStartCallbackStruct, *XmDropStartCallback;
  • reason β€” why the callback was invoked.
  • event β€” points to the XEvent that triggered the callback.
  • timeStamp β€” the time at which the drag was completed. ⏰
  • operation β€” identifies an operation. And okay, this one has layers, so pay attention:
    • If the pointer is over an active drop site when the drop begins, the toolkit initializes operation to the value of the operation member of the XmDropProcCallbackStruct at the time the DropSite's XmNdropProc returns.
    • If the pointer is not over an active drop site when the drop begins, the toolkit initializes operation by picking one out of the initial value of the operations member. It searches this set first for XmDROP_MOVE, then for XmDROP_COPY, then for XmDROP_LINK, and initializes operation to the first one it finds in the set. If it finds none of these in the set, it initializes operation to XmDROP_NOOP. Iconic search order, no notes. πŸ”₯
  • operations β€” the set of operations supported for the source data. Three whole scenarios, bestie:
    • If the pointer is over an active drop site when the drop begins, the toolkit initializes operations to the bitwise AND of the DropSite's XmNdropOperations and the value of the operations member of the XmDropProcCallbackStruct at the time the DropSite's XmNdropProc returns. If that resulting set is empty, the toolkit initializes operations to XmDROP_NOOP.
    • If the pointer is not over an active drop site when the drop begins and the user does not select an operation (by pressing a modifier key), the toolkit initializes operations to the value of the DragContext's XmNdragOperations resource.
    • If the pointer is not over an active drop site when the drop begins and the user does select an operation, the toolkit initializes operations to the bitwise AND of the corresponding operation and the value of the DragContext's XmNdragOperations resource. Empty set? Toolkit initializes operations to XmDROP_NOOP. Periodt.
  • dropSiteStatus β€” whether or not a drop site is valid:
    • If the pointer is over an active drop site when the drop begins, the toolkit initializes dropSiteStatus to the value of the dropSiteStatus member of the XmDropProcCallbackStruct at the time the DropSite's XmNdropProc returns.
    • If the pointer is not over an active drop site when the drop begins, the toolkit initializes dropSiteStatus to XmNO_DROP_SITE.
⚠️ This field is invalid if the dropAction field is set to XmDROP_CANCEL. Read that again, bestie, it matters 😭
  • dropAction β€” an IN/OUT member that identifies the drop action. The values are XmDROP, XmDROP_CANCEL, XmDROP_HELP, and XmDROP_INTERRUPT. You can modify the value of dropAction to change the action actually initiated. Heads up though: XmDROP_INTERRUPT is currently unsupported β€” if you specify it, it will be interpreted as an XmDROP_CANCEL. So like… don't πŸ’€
  • x β€” the x-coordinate of the pointer in root window coordinates.
  • y β€” the y-coordinate of the pointer in root window coordinates.

A pointer to this structure is passed to the XmNoperationChangedCallback callback:

typedef struct
{
        int reason;
        XEvent  *event;
        Time timeStamp;
        unsigned char operation;
        unsigned char operations;
        unsigned char dropSiteStatus;
}XmOperationChangedCallbackStruct, *XmOperationChangedCallback;
  • reason β€” why the callback was invoked.
  • event β€” points to the XEvent that triggered the callback.
  • timeStamp β€” the time at which the crossing event occurred. 🌸
  • operation β€” identifies an operation. And again, three branches, so let's go:
    • If the toolkit has just called a DropSite's XmNdragProc, the toolkit initializes operation to the value of the operation member of the XmDragProcCallbackStruct at the time the DropSite's XmNdragProc returns.
    • If the toolkit has not called an XmNdragProc, and the pointer is within an active drop site, the toolkit initializes operation by selecting an operation from the bitwise AND of the initial value of the operations member and the value of the DropSite's XmNdropSiteOperations resource. It searches this set first for XmDROP_MOVE, then for XmDROP_COPY, then for XmDROP_LINK, and initializes operation to the first one it finds in the set. Finds none of them? Initializes operation to XmDROP_NOOP.
    • If the toolkit has not called an XmNdragProc, and the pointer is not within an active drop site, the toolkit initializes operation by selecting an operation from the initial value of the operations member. Same search order β€” first XmDROP_MOVE, then XmDROP_COPY, then XmDROP_LINK β€” and operation becomes the first one it finds. None found? operation gets initialized to XmDROP_NOOP.
  • operations β€” the set of operations supported for the source data:
    • If the toolkit has just called a DropSite's XmNdragProc, the toolkit initializes operations to the bitwise AND of the DropSite's XmNdropOperations and the value of the operations member of the XmDragProcCallbackStruct at the time the DropSite's XmNdragProc returns. If the resulting set of operations is empty, the toolkit initializes operations to XmDROP_NOOP.
    • If the toolkit has not called an XmNdragProc, and the user does not select an operation (by pressing a modifier key), the toolkit initializes operations to the value of the DragContext's XmNdragOperations resource.
    • If the toolkit has not called an XmNdragProc, and the user does select an operation, the toolkit initializes operations to the bitwise AND of the corresponding operation and the value of the DragContext's XmNdragOperations resource. Empty set again? Toolkit initializes operations to XmDROP_NOOP. Every single time, bestie 🫢
  • dropSiteStatus β€” whether or not a drop site is valid:
    • If the toolkit has just called a DropSite's XmNdragProc, the toolkit initializes dropSiteStatus to the value of the dropSiteStatus member of the XmDragProcCallbackStruct at the time the DropSite's XmNdragProc returns.
    • If the toolkit has not called an XmNdragProc, it initializes dropSiteStatus to XmNO_DROP_SITE if the pointer is over an inactive drop site or is not over a drop site at all.
    • The toolkit initializes dropSiteStatus to XmDROP_SITE_VALID if all of the following conditions are met:
      • The pointer is over an active drop site
      • The DragContext's XmNexportTargets and the DropSite's XmNimportTargets are compatible
      • The initial value of the operation member is not XmDROP_NOOP
    • Otherwise, the toolkit initializes dropSiteStatus to XmDROP_SITE_INVALID.

A pointer to this structure is passed to the callbacks for XmNtopLevelEnterCallback:

typedef struct
{
        int reason;
        XEvent *event;
        Time timeStamp;
        Screen screen;
        Window window;
        Position x;
        Position y;
        unsigned char dragProtocolStyle;
}XmTopLevelEnterCallbackStruct, *XmTopLevelEnterCallback;
  • reason β€” why the callback was invoked.
  • event β€” points to the XEvent that triggered the callback.
  • timeStamp β€” the timestamp of the logical event.
  • screen β€” the screen associated with the top-level window or root window being entered.
  • window β€” the ID of the top-level window or root window being entered.
  • x β€” the x-coordinate of the pointer in root window coordinates.
  • y β€” the y-coordinate of the pointer in root window coordinates.
  • dragProtocolStyle β€” the protocol style adopted by the initiator. The values are XmDRAG_DROP_ONLY, XmDRAG_DYNAMIC, XmDRAG_NONE, and XmDRAG_PREREGISTER. ✨

A pointer to this structure is passed to the callbacks for XmNtopLevelLeaveCallback:

typedef struct
{
        int reason;
        XEvent  *event;
        Time timeStamp;
        Screen screen;
        Window window;
}XmTopLevelLeaveCallbackStruct, *XmTopLevelLeaveCallback;
  • reason β€” why the callback was invoked.
  • event β€” points to the XEvent that triggered the callback.
  • timeStamp β€” the timestamp of the logical event.
  • screen β€” the screen that's attached to the top-level window (or root window) you're leaving πŸ’¨
    • window β€” the ID of the top-level window or root window that's getting left behind πŸ‘‹

πŸ’« Translations πŸ’«

okay so the XmDragContext translations are all listed below, bestie. The key names follow the X standard key event translation table syntax β€” that's the exact format Motif uses to say "this key = this widget action," iykyk. There's a lil overview of the format over in VirtualBindings(3), and if you want the whole breakdown you gotta hit up the X Toolkit Intrinsics Documentation. fr fr. πŸ“š

  • Button1<Enter>: DragMotion()
  • Button1<Leave>: DragMotion()
  • Button1<Motion>: DragMotion()
  • Button2<Enter>: DragMotion()
  • Button2<Leave>: DragMotion()
  • Button2<Motion>: DragMotion()
  • <Btn2Up>: FinishDrag()
  • <Btn1Up>: FinishDrag()
  • <Key>Return: FinishDrag()
  • <Key><osfActivate>: FinishDrag()
  • <BtnDown>: IgnoreButtons()
  • <BtnUp>: IgnoreButtons()
  • :<Key><osfCancel>: CancelDrag()
  • :<Key><osfHelp>: HelpDrag()
  • :<Key><osfUp>: DragKey(Up)
  • :<Key><osfDown>: DragKey(Down)
  • :<Key><osfLeft>: DragKey(Left)
  • :<Key><osfRight>: DragKey(Right)
  • :<KeyUp>: DragKey(Update)
  • :<KeyDown>: DragKey(Update)
🌸 note bestie: those leading : marks on the osf ones? yeah, they're literally in the table. copy them exactly, don't get cute. πŸ™ˆ

🎬 Action Routines 🎬

the XmDragContext action routines are, in no particular order of slay:

  • CancelDrag() β€” cancels the whole drag operation and frees the associated DragContext. it's giving "we're so done here" πŸ’€
  • DragKey(String) β€” if String is Left, Right, Up, or Down, this moves the dragged object to the corresponding location. any other value of String? ignored. periodt. 🚫
  • DragMotion() β€” drags the selected data along as the pointer moves. main character behavior honestly ✨
  • FinishDrag() β€” finishes the drag operation and kicks off the drop operation. the handoff. the moment. πŸ”₯
  • HelpDrag() β€” initiates a conditional drop that lets the receiver give the user help info. the user can then either cancel or continue the drop in response to that info. choices, we love them 🫢

🧚 Virtual Bindings 🧚

the bindings for virtual keys are vendor specific β€” no universal answer, sorry bestie 😭. if you want the tea on bindings for virtual buttons and keys, go read VirtualBindings(3).


go read these, they're all part of the lore: Core(3), XmDisplay(3), XmDragCancel(3), XmDragIcon(3), XmDragStart(3), XmDropSite(3), XmDropTransfer(3), and XmScreen(3). that's the whole friend group πŸ’œ


and that's a wrap on the whole page, bestie!! πŸŽ€ this one's from the XmDragContext(library call) era β€” the library-call section of the manual, iconic as always. go forth and drag responsibly πŸ‘‘πŸ’