diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2009-02-05 14:18:28 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2009-02-26 15:18:30 +1000 |
commit | 27dc5a8313d48a78a628563132142a97f7a47843 (patch) | |
tree | 2b0d28a3dd87b9c82c6ff703962a6d0a99720bf9 | |
parent | f39d3c8d6035fe65ad788987e291b99ad22448dd (diff) |
Add XI2 protocol specification document.
-rw-r--r-- | XI2proto.txt | 896 |
1 files changed, 896 insertions, 0 deletions
diff --git a/XI2proto.txt b/XI2proto.txt new file mode 100644 index 0000000..bf405ee --- /dev/null +++ b/XI2proto.txt @@ -0,0 +1,896 @@ + + The X Input Extension + Version 2.0 + + Peter Hutterer + peter.hutterer@redhat.com + Red Hat, Inc. + + + +1. Introduction + +The X Input Extension version 2.0 (XI2) is the second major release of the X +Input Extension. + +FIXME + ❧❧❧❧❧❧❧❧❧❧❧ + +2. Notations used in this document + +Notation for requests: +┌─── + Name of request + name of request field: type of request field + name of request field: type of request field + ▶ + name of reply field: type of reply field +└─── + +Notation for events: +┌─── + Name of event + name of field: type of field + name of field: type of field +└─── + +Complex fields are specified in the following notation: + name of field: COMPLEXFIELDTYPE +or, if multiple of these fields exist: + name of field: LISTofCOMPLEXFIELDTYPE + +COMPLEXFIELDTYPE: { name of subfield: type of subfield, + name of subfield: type of subfield } + + ❧❧❧❧❧❧❧❧❧❧❧ + +3. Interoperability between version 1.x and 2.0 + +FIXME + + ❧❧❧❧❧❧❧❧❧❧❧ + +4. The Master/Slave device hierarchy + +XI2 introduces a device hierarchy split up into so-called Master Devices (MD) +and Slave Devices (SD). + +4.1 Master devices +An MD is a virtual device created and managed by the server. MDs may send core +events and XI events. However, an MD does not represent a physical device and +relies on SDs for event generation. MDs come in two forms: as master pointers +or as master keyboards. A master pointer is represented by a visible cursor on +the screen. A master keyboard is represented by a keyboard focus. + +Each master pointer is paired with the respective master keyboard and vice +versa, and this pairing is constant for the lifetime of both input devices. +Clients can use this pairing behaviour to implement input paradigms that +require pointer and keyboard interation (e.g. SHIFT + Click). + +4.2 Slave devices +An SD is usually a physical device configured in the server. SDs are not +represented by a cursor or keyboard focus and may be attached to a master +pointer or master keyboard. SDs can only be attached to any master of the same +type (e.g. a physical pointer device can be attached to any master pointer). + +If an event is generated by an SD +- if the SD is attached to a master pointer, it changes the position and/or + button state of the master pointer. +- if the SD is attached to a master keyboard, it sends events to this + keyboard's focus window (if applicable) and/or changes the modifier state of + this keyboard. +- if the SD is not attached to an SD ("floating"), it does not change the + any master device. The SD has its own (invisible) sprite and its own focus. + Both the sprite and the focus must be managed explicitly by the client + program. + +4.3 Event processing for attached slave devices + +Whenever an SD changes its logical state, +- the event is delivered as an XI event to any interested clients. If the + device is floating, event processing stops. + Otherwise, if the device is attached, +- the master device changes its classes to reflect the SD's capabilities. All + interested clients are notified of this device change. +- then, the event is delivered as an XI event from the MD to any interested + clients. If the event has been delivered, event processing stops. + Otherwise, +- the event is delivered as a core event to any interested clients. + +Given that W is the event window, and P the parent window of W, event delivery +to P is only attempted if neither the XI event, nor the core event has been +delivered on W. Once an event has been delivered as either XI or core event, +event processing stops. + + ❧❧❧❧❧❧❧❧❧❧❧ +5. Data types + +BUTTONMASK + A binary mask defined as (1 << button number). + A SETofBUTTONMASK is a binary OR of zero or more BUTTONMASK. + +DEVICE { DEVICEID, AllDevices, AllMasterDevices } + A DEVICE specifies either a DEVICEID or AllDevices or + AllMasterDevices. + +DEVICEID { CARD16 } + A DEVICEID is a numerical ID for a device currently available in the + server. The server may re-use a device ID after a device's removal. + The device IDs 0 and 1 are reserved. + AllDevices ........ 0 + AllMasterDevices .. 1 + +DEVICEUSE { MasterPointer, MasterKeyboard, SlavePointer, + SlaveKeyboard, FloatingSlave } + A DEVICEUSE field specifies the current use of a device in the MD/SD + device hierarchy. See Section 4 for more information. + +EVENTMASK + An EVENTMASK is a binary mask defined as (1 << event type). + A SETofEVENTMASK is a binary OR of zero or more EVENTMASK. + +FP1616 + Fixed point decimal in 16.16 format as 32 bit integer in the form of + (value * 10e15). The client is required to convert to 16.16 decimal + format. + +FP3232 + Fixed point decimal in 32.32 format as one INT32 and one CARD32. + The INT32 contains the integral part, the CARD32 the decimal fraction + shifted by 32. + +VALUATORMASK + A binary mask defined as (1 << valuator number). + A SETofVALUATORMASK is a binary OR of zero or more VALUATORMASK. + + ❧❧❧❧❧❧❧❧❧❧❧ +6. Errors + +Errors are sent using core X error reports. + +Device + A value for a DEVICE argument does not specify a valid DEVICE. + + ❧❧❧❧❧❧❧❧❧❧❧ +7. Requests: + +The server does not guarantee that the length of a reply remains constant in +future revisions of XI2. A client must always retrieve the exact length of the +protocol reply from the connection, even if the reply is longer than defined +for the XI2 version supported by the client. +Additional bytes in a request may include data supported in later versions of +XI2. Clients should ignore this data. + +7.1 Requests introduced in version 2.0 + + ┌─── + XIQueryVersion + major_version: CARD16 + minor_version: CARD16 + ▶ + major_version: CARD16 + minor_version: CARD16 + └─── + + The client sends the highest supported version to the server and the + server sends the highest version it supports, but no higher than the + requested version. Major versions changes can introduce incompatibilities + in existing functionality, minor version changes introduce only backward + compatible changes. It is the clients responsibility to ensure that the + server supports a version which is compatible with its expectations. + + major_version + Major XI2 version. + minor_version + Minor XI2 version. + + ┌─── + XIQueryDevice + DEVICE deviceid + ▶ + num_devices: CARD16 + deviceinfo: LISTofDEVICEINFO + └─── + + DEVICEINFO { deviceid: DEVICEID + use: DEVICEUSE + attachment: DEVICEID + enabled: BOOL + num_classes: CARD16 + name_len: CARD16 + name: LISTofCHAR8 + classes: LISTofCLASS } + + CLASS { BUTTONCLASS KEYCLASS, AXISCLASS } + + BUTTONCLASS { type: ButtonClass + length: CARD16 + num_buttons: CARD16 + buttons: LISTofATOM } + + KEYCLASS { type: KeyClass + length: CARD16 + num_keys: CARD16 + keys: LISTofCARD32 } + + AXISCLASS { type: AxisClass + length: CARD16 + axisnumber: CARD16 + axisname: ATOM + min: FP3232 + max: FP3232 + resolution: CARD32 } + + XIQueryDevices details information about the requested input devices. + + devices + The device to list. If 'devices' is AllDevices, all enabled and + disabled devices are listed. If 'devices' is AllMasterDevices, all + enabled and disabled master devices are listed. If 'devices' is a + valid DEVICE, only this DEVICE is listed and 'num_devices' is 1. + num_devices + The number of 'deviceinfos' returned. + + Each 'deviceinfo' is detailed as follows: + deviceid + The unique ID of the device. Device IDs may get re-used when a device + is removed. + use + If the device is a master pointer, 'use' is MasterPointer. + If the device is a master keyboard, 'use' is MasterKeyboard. + If the device is a slave pointer, 'use' is SlavePointer. + If the device is a slave keyboard, 'use' is SlaveKeyboard. + If the device is a floating slave, 'use' is FloatingSlave. + + attachment + If the device is a master pointer or a master keyboard, 'attachment' + specifies the paired master keyboard, or the paired master pointer, + respectively. If the device is a non-floating slave device + 'attachment' specifies the master device this device is attached to. + If the device is a floating slave, 'attachment' is undefined. + + enabled + Zero if the device is disabled, non-zero otherwise. + num_classes + Number of 'classes' provided. + name_len + Length of the name in bytes. + classes + Details the available classes provided by the device in an undefined + order. + name + The device's name, padded to a multiple of 4 bytes. + + For all classes, 'type' specifies the device class. Clients are required + to ignore unknown device classes. The 'length' field specifies the length + of the class in 4 byte units. + The following classes may occur only once: ButtonClass, KeyClass + + ButtonClass: + type + Always ButtonClass. + length + Length in 4 byte units. + num_buttons + Number of buttons provided by the device. + buttons + List of Atoms specifying the type of each button. An atom of None + specifies an unnamed button. Buttons are listed in the device-native + order and potential button mappings are ignored. + + KeyClass: + type + Always KeyClass. + length + Length in 4 byte units. + num_keys + Number of keycodes provided by the device. + keys + List of keycodes provided. + + AxisClass: + type + Always AxisClass. + length + Length in 4 byte units. + axisnumber + Axis number of this axis. The axis number is in device-native + order and potential axis mappings are ignored. + axisname + Atom specifying the axis name. An Atom of None specifies an unnamed + axis. + min + Minimum value. + max + Minimum value. + resolution + Resolution in counts/meter. + mode + Relative or Absolute. + + An axis in Relative mode may specify 'min' and 'max' as a hint to the + client. If no 'min' and 'max' information is available, both must be 0. + + ┌─── + XISelectEvents + window: Window + num_masks: CARD16 + masks: LISTofDEVICEEVENTMASK + + └─── + + DEVICEEVENTMASK { deviceid: DEVICE, + mask_len: CARD16, + mask: SETofEVENTMASK + + window + The window to select the events on. + num_masks + Number of items in mask. + deviceid + Numerical deviceid, or AllDevices, or AllMasterDevices. + mask_len + Length of mask in 4 byte units. + mask + Event mask. An event mask for an event type T is defined as (1 << T). + + XISelectEvents selects for XI2 events on 'window'. + + If 'num_masks' is 0, a BadValue error occurs. + + Each 'mask' sets the (and overwrites a previous) event mask for the DEVICE + specified through 'deviceid'. The device 'AllDevices' or + 'AllMasterDevices' is treated as a separate device by server. A client's + event mask is the union of 'AllDevices', 'AllMasterDevices' and the + per-device event mask. + The removal of device from the server unsets the event masks for the + device. If an event mask is set for AllDevices or AllMasterDevices, the + event mask is not cleared on device removal and affects all future + devices. + + If 'mask_len' is 0, the event mask for the given device is cleared. + + ┌─── + XIQueryDevicePointer + window: Window + deviceid: DEVICEID + ▶ + root: Window + child: Window + root_x: FP1616 + root_y: FP1616 + win_x: FP1616 + win_y: FP1616 + same_screen: BOOL + └─── + + Query a master pointer device for its current position. + + root + The root window the pointer is logically on. + child + The child window of 'window' that contains the pointer or None. + root_x + root_y + Pointer position relative to the root window's origin. + win_x + win_y + Pointer position relative to 'window' or 0 if 'same_screen' is false. + same_screen + TRUE if 'window' is on the same screen as the pointer. + + ┌─── + XIWarpDevicePointer + src_win: Window + dst_win: Window + src_x: FP1616 + src_y: FP1616 + src_width: INT16 + src_height: INT16 + dst_x: FP1616 + dst_y: FP1616 + deviceid: DEVICEID + └─── + + WarpDevicePointer moves the pointer of 'deviceid' as if the user had moved + the pointer. WarpDevicePointer can only be called for MasterPointer and + FloatingSlave devices. + + src_win + If src_window is not None, the move only takes place if src_window + contains the pointer and the pointer is contained in the specified + rectangle of src_window. + dst_win + If dst_win is None, this request moves the pointer by offsets + 'dst_x'/'dst_y' relative to the current position of the pointer. If + dst_window is a window, this request moves the pointer to + 'dst_x'/'dst_y' relative to dst_win's origin. + src_x + src_y + src_width + src_height + Specifies the source window rectangle. + dst_x + dst_y + The relative coordinates to move the pointer if 'dst_win' is None, or + the absolute coordinates if 'dst_win' is a window. + deviceid + The device to warp. + + This request cannot be used to move the pointer outside the confine-to + window of an active pointer grab. An attempt will only move the pointer as + far as the closest edge of the confine-to window. + + This request will generate events just as if the user had instantaneously + moved the pointer. + + ┌─── + XIChangeDeviceCursor + win: Window + cursor: Cursor + deviceid: DEVICEID + └─── + + Change a master pointer's cursor on the specified window. + + window + The window. + cursor + The new cursor or None. + deviceid + The master pointer device. + + Whenever 'device' enters a window W, the cursor shape is selected in the + following order: + - if the current window has a device cursor C(d) defined for 'device', + display this cursor C(d). + - otherwise, if the current window has a cursor C(w) defined in the core + protocol's window attributes, display cursor C(w). + - repeat on parent window until a cursor has been found. + + ┌─── + XIChangeDeviceHierarchy + num_changes: CARD8 + changes: LISTofHIERARCHYCHANGES + └─── + + HIERARCHYCHANGE { CREATEMASTER, REMOVEMASTER, ATTACHSLAVE, DETACHSLAVE } + + HIERARCHYCHANGETYPE { CreateMaster, RemoveMaster, AttachSlave, DetachSlave } + + CHANGEMODE { Float, Attach } + + CREATEMASTER { type: HIERARCHYCHANGETYPE + length: CARD16 + name_len: CARD16 + send_core: BOOL + enable: BOOL + name: LISTofCHAR8 } + + REMOVEMASTER { type: HIERARCHYCHANGETYPE + length: CARD16 + deviceid: DEVICEID + return_mode: CHANGEMODE + return_pointer: DEVICEID + return_keyboard: DEVICEID } + + ATTACHSLAVE { type: HIERARCHYCHANGETYPE + length: CARD16 + deviceid: DEVICEID + master: DEVICEID } + + DETACHSLAVE { type: HIERARCHYCHANGETYPE + length: CARD16 + deviceid: DEVICEID } + + XIChangeDeviceHierarchy allows a client to modify the MD/SD device + hierarchy (see Section 4). + + num_changes + The number of changes to apply to the current hierarchy. + changes + The list of changes. + + The server processes the changes one by one and applies changes + immediately. If an error occurs, processing stops at the current change + and returns the number of successfully applied changes in the error. + + CREATEMASTER creates a pair of master devices. + type + Always CreateMaster. + length + Length in 4 byte units. + name_len + Length of 'name' in bytes. + send_core + TRUE if the device should send core events. + enable + TRUE if the device is to be enabled immediately. + name + The name for the new master devices. The master pointer's name is + automatically appended with " pointer", the master keyboard's name is + automatically appended with " keyboard". + + REMOVEMASTER removes an existing master device. + type + Always RemoveMaster. + length + Length in 4 byte units. + deviceid + The device to remove. + return_mode + Return mode for attached slave devices. + If 'return_mode' is Float, all slave devices are set to floating. + If 'return_mode' is Attach, slave pointers are attached to + 'return_pointer' and slave keyboards are attached to + 'return_keyboard'. + return_pointer + return_keyboard + The master pointer and master keyboard to attach slave devices to, if + 'return_mode' is Attach. + + Removing a master pointer removes the paired master keyboard and vice + versa. + + ATTACHSLAVE attaches a slave device to a given master device. + type + Always ChangeAttachment. + length + Length in 4 byte units. + deviceid + Deviceid of the slave device. + master + The new master device to attach this slave device to. + + DETACHSLAVE detaches a slave device from its current master device. + type + Always ChangeAttachment. + length + Length in 4 byte units. + deviceid + Deviceid of the slave device. + + ┌─── + XISetClientPointer + win: Window + deviceid: DEVICEID + └─── + + Set the ClientPointer for the client owning 'win' to the given device. + + win + Window or client ID. + deviceid + The master pointer or master keyboard that acts as ClientPointer. + + Some protocol requests are ambiguous and the server has to choose a device + to provide data for a request or a reply. By default, the server will + choose a client's ClientPointer device to provide the data, unless the + client currently has a grab on another device. + + ┌─── + XIGetClientPointer + win: Window + ▶ + set: BOOL + deviceid: DEVICEID + └─── + + Query the ClientPointer for the client owning 'win'. + + win + The window or client ID. + set + TRUE if the client has an explicitly set ClientPointer. + deviceid + The master pointer that acts as a ClientPointer if 'set' is TRUE. + +8. Events: + +An event specifies its length in 4-byte units after the initial 32 bytes. +Future versions of the protocol may provide additional information +in the same event, thus increasing the event size. Clients are required to +always read the number of bytes specified by the event, not the size of the +event they may have been compiled against. + + +The following event types are available in XI2. + +Version 2.0: + HierarchyChanged + DeviceChanged + KeyPress + KeyRelease + ButtonPress + ButtonRelease + Motion + RawEvent + Enter + Leave + +All events have a set of common fields specified as EVENTHEADER. + + +EVENTHEADER { type: BYTE + extension: BYTE + sequenceNumber: CARD16 + length: CARD32 + evtype: CARD16 + deviceid: DEVICEID + time: Time } + + type + Always GenericEvent. + extension + Always the X Input extension offset. + sequenceNumber + Sequence number of last request processed by the server. + length + Length in 4-byte units after the initial 32 bytes. + evtype + XI-specific event type. + deviceid + Numerical device id for a device. + time + Time in ms. + + + ┌─── + DeviceHierarchyEvent: + EVENTHEADER + flags: SETofHIERARCHYMASK + num_devices: CARD16 + deviceinfo: LISTofHIERARCHYINFO + └─── + + + HIERARCHYMASK { MasterAdded, MasterRemoved, SlaveAttached, SlaveDetached, + SlaveAdded, SlaveRemoved, DeviceEnabled, DeviceDisabled } + + HIERARCHYINFO { deviceid: DEVICEID, + attachment: DEVICEID, + type: DEVICEUSE + enabled: BOOL } + + flags + Set of the changes that have occured, causing this event. + num_devices + The number of devices present in the hierarchy. + devices + The current hierarchy layout for each device. + + An XDeviceHierarchyEvent is sent whenever the device hierarchy been + changed. The 'flags' specify all types of hierarchy modifiations that have + occured. + For all devices, 'deviceinfo' details the hierarchy information after the + modification of the hierarchy has occured. For each device specified with + 'deviceid': + - if 'type' is MasterPointer or MasterKeyboard, 'attachment' decribes the + pairing of this device. + - if 'type' is SlavePointer or SlaveKeyboard, 'attachment' describes the + master device this device is attached to. + - if 'type' is FloatingSlave device, 'attachment' is undefined. + + enabled + TRUE if the device is enabled and can send events. A disabled master + device will not forward events from an attached, enabled slave + device. + + Note: Multiple devices may be affected in one hierarchy change, + 'deviceid' in an XDeviceHierarchyChangedEvent is always the first affected + device. Clients should ignore deviceid and instead use the 'devices' list. + + ┌─── + DeviceChangedEvent: + EVENTHEADER + reason: CHANGEREASON + source: DEVICEID + num_classes: CARD16 + classes: LISTofCLASS + └─── + + CHANGEREASON { SlaveSwitch, DeviceChange } + + A DeviceChangeEvent is sent whenever a device changes it's capabilities. + This can happen either by a new slave device sending events through a + master device, or by a physical device changing capabilities at runtime. + + reason + The reason for generating this event. + If 'reason' is SlaveSwitch, the slave device sending events through + this device has changed and 'source' specifies the new slave device. + A SlaveSwitch 'reason' can only occur on a master device. + If 'reason' is DeviceChange, the device itself has changed through + other means (e.g. a physical device change) and 'source' is + undefined. A DeviceChange can only occur on a slave device. + source + The source of the new classes. Only defined in 'reason' is + SlaveSwitch. + num_classes + Number of 'classes' provided. + classes + Details the available classes provided by the device. The order the + classes are provided in is undefined. + + For a detailed description of 'classes', see the XQueryInputDevice + request. + + ┌─── + DeviceEvent: + EVENTHEADER + detail: CARD32 + root: Window + event: Window + child: Window + root_x: FP1616 + root_y: FP1616 + event_x: FP1616 + event_y: FP1616 + buttons_len: CARD16 + valuators_len: CARD16 + sourceid: DEVICEID + mods: MODIFIERINFO + group: GROUPINFO + buttons: SETofBUTTONMASK + valuators: SETofVALUATORMASK + axisvalues: LISTofFP3232 + └─── + + BUTTONBIT { (1 << Button1), (1 << Button2), ... , (1 << ButtonN) } + VALUATORBIT { (1 << 1), ( 1 << 2), ... ( 1 << n) } + + MODIFIERINFO { base_mods: CARD32, + latched_mods: CARD32, + locked_mods: CARD32} + GROUPINFO { base_group: CARD8, + latched_group: CARD8, + locked_group: CARD8 } + + An XDeviceEvent is generated whenever the logical state of a device + changes in response to a button press, a button release, a motion, a key + press or a key release. + + detail + The button number or key code, or 0. + root + event + child + The root window, event window or subwindow, respectively. See core + protocol specification for more detail. + root_x + root_y + The position of the pointer in screen coordinates (16.16 fixed point). + event_x + event_y + The position of the pointer in screen coordinates relative to the + event window (16.16 fixed point). + + buttons_len + The length of 'buttons' in 4 byte units. + valuators_len + The length of 'valuators' in 4 byte units. + sourceid + The source device that originally generated the event. + mods + XKB modifier state before the event occured. + group + XKB group state before the event. + buttons + Button state before the event. + valuators + Bitmask of valuators provided in 'axisvalues'. + axisvalues + Valuator data in device-native resolution. + + Modifier state in 'mods' is detailed as follows: + base_mods + XKB base modifier state. + latched_mods + XKB latched modifier state. + locked_mods + XKB locked modifier state. + + Group state in 'group' is detailed as follows: + base_group + XKB base group state. + latched_group + XKB latched group state. + locked_group + XKB locked group state. + + ┌─── + RawEvent + EVENTHEADER + eventtype: RAWTYPE + detail: CARD32 + buttons_len: CARD16 + valuators_len: CARD16 + buttons: SETofBUTTONMASK + valuators: SETofVALUATORMASK + axisvalues: LISTofFP3232 + axisvalues_raw: LISTofFP3232 + └─── + + RAWTYPE { Motion, KeyPress, KeyRelease, ButtonPress, ButtonRelease } + + A RawDevice event provides the information provided by the driver to the + client. RawDevice events are only generated for slave devices and provide + both the raw data as supplied by the driver and transformed data as used + in the server. Transformations include, but are not limited to, axis + clipping and acceleration. + Transformed valuator data may be equivalent to raw data. In this case, + both raw and transformed valuator data is provided. + RawDeviceEvents are sent exclusively to all root windows or to the client + that grabbed the device only. + + eventtype + The type of event that occured on the device. + detail + The button number or keycode. + buttons_len + The length of 'buttons' in 4 byte units. + valuators_len + The length of 'valuators' in 4 byte units. + buttons + Button state before the event. + valuators + Bitmask of valuators provided in 'axisvalues' and 'axisvalues_raw'. + axisvalues + Valuator data in device-native resolution. + axisvalues_raw + Untransformed valuator data in device-native resolution. + + ┌─── + Enter or Leave + EVENTHEADER + root: Window + event: Window + child: Window + sourceid: DEVICEID + root_x: FP1616 + root_y: FP1616 + event_x FP1616 + event_y: FP1616 + mode: NOTIFYMODE + detail: NOTIFYDETAIL + same_screen: BOOL + focus: BOOL + └─── + + NOTIFYMODE { Normal, Grab, Ungrab } + NOTIFYDETAIL { Ancestor, Virtual, Inferior, Nonlinear, NonlinearVirtual, + Pointer, PointerRoot, None } + + Enter or Leave events are sent whenever a device's pointer enters or + leaves a window. + The enter/leave model is described in the core protocol specification, + Section 11. (EnterNotify, LeaveNotify events). + + root + event + child + The root window, event window, and child window, respectively. See the + core protocol specification for more detail. + sourceid + The device that caused the pointer to move. + root_x + root_y + The pointer coordinates relative to the root window. + event_x + event_y + The pointer coordinates relative to the event window. + mode + Normal pointer motion events have mode Normal. Pseudo-motion events + when a grab activates have mode Grab, and pseudo-motion events when a + grab deactivates have mode Ungrab. + detail + Specifies the relation of the event window to the window the pointer + entered or left. See the core protocol spec for details. + same_screen + TRUE if the event window is on the same screen as the pointer's root + window. + focus + If the event window is the focus window or an inferior of the focus + window, then focus is True. Otherwise, focus is False. + + ❧❧❧❧❧❧❧❧❧❧❧ |