TkDND(n) Tk Built-In Commands TkDND(n)______________________________________________________________________________NAMETkDND - Tk Drag and Drop Interface
SYNOPSIS
tkdnd::drop_target register window ?type-list?
tkdnd::drop_target unregister window
tkdnd::drag_source register window ?type-list? ?mouse-button?
tkdnd::drag_source unregister window
tkdnd::platform_specific_types type-list
tkdnd::platform_independent_types type-list
tkdnd::GetDropFileTempDirectory
tkdnd::SetDropFileTempDirectory directory
INTRODUCTION
The TkDND family commands provide a Tcl interface to native, platform
specific drag and drop mechanism. Under Unix the drag & drop protocol
in use is the XDND protocol version 5 (also used by the Qt toolkit, and
the KDE and GNOME desktops). Under Windows, the OLE2 drag & drop
interfaces are used. Under Macintosh, the Cocoa drag and drop inter‐
faces are used.
The TkDND family can be built from source code using the standard con‐
figure; make; make install procedure. Cmake is also supported. Some
binary package are available from the SourceForge download site, from
ActiveState's ActiveTcl distribution, and elsewhere.
With the TkDND family commands the user is able to register existing Tk
widgets as drag sources or drop targets, that are able to send or
receive data during drag and drop operations, encoded in specific
types. These types can be platform independent types like DND_Text and
DND_Files or platform specific types, like CF_UNICODETEXT or
text/plain.
The legal forms for the TkDND commands are:
tkdnd::drop_target register window ?type-list?
This command will register window as a drop target. A drop tar‐
get is a widget than can accept a drop action. window must exist
when this command is executed and this command can be executed
multiple times on a widget.
When window is registered as a drop target, and optional type-
list can be provided. This type list can contain one or more
types that window will accept during a drop action, and it can
contain platform independent or platform specific types. Plat‐
form independent are DND_Text for dropping text portions and
DND_Files for dropping a list of files (which can contain one or
multiple files) on window. If type-list is not specified, it
defaults to the empty list.
tkdnd::drop_target unregister window
This command will stop window from being a drop target. Thus,
window will stop receiving events related to drop operations.
It is an error to use this command for a window that has not
been registered as a drop target with tkdnd::drop_target regis‐
ter.
tkdnd::drag_source register window ?type-list? ?mouse-button?
This command will register window as a drag source. A drag
source is a widget than can start a drag action. window must
exist when this command is executed and this command can be exe‐
cuted multiple times on a widget.
When window is registered as a drag source, and optional type-
list can be provided. This type list can contain one or more
types that window will provide during a drag action, and it can
contain platform independent or platform specific types. Plat‐
form independent are DND_Text for dropping text portions and
DND_Files for dropping a list of files (which can contain one or
multiple files) on window. However, this type list is indica‐
tive/informative. window can initiate a drag action with even a
different type list. If type-list is not specified, it defaults
to the empty list.
Finally, mouse-button is the mouse button that will be used for
starting the drag action. It can have any of the values 1 (left
mouse button), 2 (middle mouse button - wheel) and 3 (right
mouse button). If mouse-button is not specified, it defaults to
1.
tkdnd::drag_source unregister window
This command will stop window from being a drag source. Thus,
window will stop receiving events related to drag operations.
It is an error to use this command for a window that has not
been registered as a drag source with tkdnd::drag_source regis‐
ter.
tkdnd::platform_specific_types type-list
This command will accept a list of types that can contain plat‐
form independent or platform specific types. A new list will be
returned, where each platform independent type in type-list will
be substituted by one or more platform specific types. Thus, the
returned list may have more elements than type-list.
tkdnd::platform_independent_types type-list
This command will accept a list of types that can contain plat‐
form independent or platform specific types. A new list will be
returned, where each platform specific type in type-list will be
substituted by one or more platform independent types. Thus, the
returned list may have more elements than type-list.
tkdnd::GetDropFileTempDirectory
This command will return the temporary directory used by TkDND
for storing temporary files. When the package is loaded, this
temporary directory will be initialised to a proper directory
according to the operating system. This default initial value
can be changed to be the value of the following environmental
variables: TKDND_TEMP_DIR, TEMP, TMP.
tkdnd::SetDropFileTempDirectory directory
This command will change the temporary directory used by TkDND
for storing temporary files to directory.
SUPPORTED TYPES
In order to declare the format that the data that will transferred dur‐
ing a drag and drop operation, all drag and drop protocols use the
notion of types. Unfortunately, each protocol defines its own, usually
platform specific, types. TkDND, trying to maintain portability among
different platforms, offers some predefined types for some basic kinds
of data, like text, and filenames. Currently, the following predefined
cross-platform values are available:
DND_Text:
This type can be used for transferring textual data. Internally,
it is translated to the following platform specific formats:
Windows: CF_UNICODETEXT, CF_TEXT.
Unix: text/plain;charset=UTF-8, text/plain.
Mac: NSStringPboardType.
DND_Files:
This type can be used for transferring a list of file names.
Internally, it is translated to the following platform specific
formats:
Windows: CF_HDROP.
Unix: text/uri-list.
Mac: NSFilenamesPboardType.
Additionally to the platform independent types, TkDND supports the fol‐
lowing platform specific types:
Windows:
CF_UNICODETEXT: Text transfer encoded in Unicode.
CF_TEXT: Text transfer with application dependent encoding. If an
encoding locale is specified through CF_LOCALE it is used, else
the system encoding is used for the conversion.
FileGroupDescriptor - FileContents: These two types are used for
transferring a set of files that do not appear physically on disk,
like files from compressed folders or Outlook e-mail messages.
File names are transferred as in the CF_TEXT type, while file con‐
tents are transferred in binary. TkDND retrieves both the file
names and the file contents, and saves then in a temporary direc‐
tory. When the transfer is complete, the file names of the saved
files in the temporary folder are returned. Note that TkDND sup‐
port this type pair only as drop targets and not as drag sources.
FileGroupDescriptorW - FileContents: These two types are used for
transferring a set of files that do not appear physically on disk,
like files from compressed folders or Outlook e-mail messages.
File names are transferred as in the CF_UNICODETEXT type, while
file contents are transferred in binary. TkDND retrieves both the
file names and the file contents, and saves then in a temporary
directory. When the transfer is complete, the file names of the
saved files in the temporary folder are returned. Note that TkDND
support this type pair only as drop targets and not as drag
sources.
CF_HDROP: Files transfer encoded in UTF-8.
Unix:
Finally, format types used for drop types can have wildcards, following
the same rules as "string match". For example, registering a drop tar‐
get with the type "*", will accept any drop, no matter what the drop
format is.
EVENTS
Windows registered as either drop targets or drag sources, will receive
certain events, during drag and drop operations. As a result, the win‐
dows are expected to have bindings for some of these events. Some
events are mandatory (in the sense that a drag or drop operation can be
stopped if the bindings do not exist), while others are not. However,
it is a good practice to define bindings for all events, so as the
application will behave as expected during drag and drop operations.
The TkDND package defines a set of virtual events, that correspond to
various phases of a drag and drop operation. All windows that are
either a drop target or a drag source are expected to have bindings for
(all) these events, created with the bind Tk command. While these event
bindings are regular Tk events, they have a small difference from plain
Tk events: most of them are expected to return a value. Since Tk bind‐
ings cannot return a value, TkDND does not actually generate these
events (i.e. through "event generate"). Instead, TkDND locates the
script that has been bound to the virtual event, and directly executes
it, as a script. Apart from this small difference in how the events are
triggered, the events required by TkDND can be viewed as regular
events. In the following two sections all virtual events defined by the
TkDND package are presented.
DROP TARGET EVENTS
A window registered as a drop target, is expected to have bindings for
the following virtual events:
<<DropEnter>>:
This event is triggered when the mouse enters the window during
a drop action. The purpose of this event is to change the visual
state of the window, so as to notify the user whether the drop
will be accepted or not. The binding script is expected to
return a single value that will define the drop action. This
returned action can be one of copy, move, link, ask, private and
refuse_drop. This event is not mandatory, but if it is defined,
it has to return an action. In case an action is not returned,
the drop is refused for this window.
<<DropPosition>>:
This events is triggered when the mouse moves inside the window
during a drop action. The purpose of this event is to let window
decide if it will accept the drop and the action of the drop, if
a drop is going to happen at the specific mouse coordinates.
Thus, the script binding for such an event can get the mouse
coordinates and the pressed modifier buttons (such as ctrl,
shift or alt), and is expected to return the drop action, which
again must be one of copy, move, link, ask, private and
refuse_drop. This event is not mandatory, but if it is defined,
it has to return an action. In case an action is not returned,
the drop is refused for this window.
<<DropLeave>>:
This event is triggered when the mouse leaves outside the area
covered by window, without a drop happening. The binding of such
an event is expected to restore the visual state of the window
to normal (i.e. the visual state the window was in before the
<<DropEnter>> event was triggered). The binding for such an
event is not expected to return a value.
<<Drop>>:
This event is triggered by a drop action, and it is expected to
handle the dropped data and reset the visual state of the win‐
dow. The binding script is expected to return a value, which
will be the action that has been performed to the data and must
be one of copy, move, link, ask, private and refuse_drop. This
event is not mandatory, but if it is defined, it has to return
an action. In case an action is not returned, the drop is
refused for this window.
<<Drop:type>>:
This event is a specialisation of the generic <<Drop>> event,
augmented with a type. If such a binding exists and the drop
type matches type, this event binding will be executed, instead
of the generic <<Drop>> event binding. These events allow for
easy specialisation of drop bindings, according to the type of
the dropped data. type can be either a platform independent or a
platform specific type. The binding script of such an event is
expected to return a value, which will be the action that has
been performed to the data and must be one of copy, move, link,
ask, private and refuse_drop. This event is not mandatory, but
if it is defined, it has to return an action. In case an action
is not returned, the drop is refused for this window.
DRAG SOURCE EVENTS
A window registered as a drag source, is expected to have bindings for
the following virtual events:
<<DragInitCmd>>:
This event is triggered when a drag action is about to start.
This is a mandatory event (whose absence will cancel the drag
action), and is responsible for providing three things: the list
of actions and format types supported by the drag source, and of
course the data to be dropped. Thus, the binding script for such
an event must return a list of three elements: the drop actions
supported by the drag source (which can be any of copy, move,
link, ask, and private), the format type list that the data can
be dropped as (which can be any platform independent or platform
specific type), and finally the data. A simple example of such a
binding, is:
bind .drag_source <<DragInitCmd>> \
{list copy DND_Text {Hellow world!}}
<<DragEndCmd>>:
This event is triggered when the drag action has finished
(either when the drop was successful or not). Its main purpose
is to process the dropped data according to the drop action
returned by the drop target. Binding for such an event is not
mandatory, and the binding is not expected to return a value.
BINDING SCRIPTS AND SUBSTITUTIONS
All bindings scripts defined for any of the virtual events above will
be executed in the same interpreter that was used for creating the win‐
dow the event is bound to, and the binding script will executed at the
global level (i.e. only global variables will be accessible).
If the binding script contains any % characters, then substitutions
will be made, like in normal Tk binding scripts. Valid % specifiers
are:
%% Replaced with a single percent.
%A The current action of the drag/drop operation.
%a The action list supported by the drag source.
%b The mouse button that is pressed during a drag/drop operation.
Note that always a single mouse button is reported as pressed,
even if more than one mouse buttons are actually pressed.
%c The codes of the list of types supported by the drag source. All
codes are in octal format and have the same order as the list of
types obtained through the %t substitution.
%C The code (in octal format) of the current type of the drag and
drop operation.
%CTT The list of types from the drop target type list that are common
to the drag source type list.
%CST The list of types from the drag source type list that are common
to the drop target type list.
%D The data that has been dropped. Under some platforms the data will
be available before the drop has occurred. The format of the data
is the current type of the drop operation.
%e The name of the current virtual event. One of <<DropEnter>>,
<<DropPosition>>, <<DropLeave>>, <<Drop:type>>, <<Drop>>,
<<DragInitCmd>>, <<DragEndCmd>>.
%L The list of types supported by the drag source.
%m The list of modifier keyboard keys that are pressed. Modifier
keys are some special keys, like Shift, Control or Alt. Valid
modifiers are "shift", "ctrl" and "alt". It is useful for binding
scripts of drop target events to examine this list of modifiers,
as it is quite usual to change the action according to the state
of some modifier keys.
%ST The list of types supported by the drag source.
%t The list of types supported by the drag source.
%T The current type of the drag and drop operation.
%TT The list of types supported by the drop target.
%W The window that the event is delivered to.
%X The mouse pointer x coordinate, relative to the root window.
%Y The mouse pointer y coordinate, relative to the root window.
SPECIFYING DROP TARGETS
Creating drop targets is easy: we have to only register a window as a
drop target with the list of format types it can accept, and add a few
bindings. For example, a window that accepts textual drops can be as
follows:
label .drop_target -text {Text Drop Target!} -bg white
tkdnd::drop_target register .drop_target DND_Text
bind .drop_target <<DropEnter>> {%W configure -bg yellow; list copy}
bind .drop_target <<DropPosition>> {list copy}
bind .drop_target <<DropLeave>> {%W configure -bg white}
bind .drop_target <<Drop>> {%W configure -text %D; %W configure -bg white}
From the above bindings, none is obligatory. However, we usually want
to receive dropped data (thus the <<Drop>> event must be handled) and
we want to give visual feedback to the users through the <<DropEnter>>
and <<DropLeave>> events. Finally, <<DropPosition>> is only necessary
if we want to only accept drops on specific areas of the window, or we
want to change the drop action according to the pressed modifiers.
Now, if we want to also add the ability to receive file drops, we could
add:
tkdnd::drop_target register .drop_target DND_Files
bind .drop_target <<Drop:DND_Files>> \
{puts %D; %W configure -bg white}
Note that we have added a "specialised" drop binding, for the event
<<Drop:DND_Files>>: this means that when a text portion is dropped over
the window, the <<Drop>> event binding will be executed. But when a
list of files is dropped onto the window, the <<Drop:DND_Files>> event
binding will be executed. If we proceed and define a binding for the
<<Drop:DND_Text>> event, the binding of the "general" <<Drop>> event
will never be executed.
SPECIFYING DRAG SOURCES
In order to specify a drag source, we need to register a window as a
drag source:
tkdnd::drag_source register .text_drag_source
The above command defines a drag source with an empty type list (and
which will be declared in the <<DragInitCmd>> event binding) and
arranges mouse bindings such as a drag will be started with the left
mouse button. Then, it is absolutely necessary to define a binding for
the <<DragInitCmd>>: this event binding must return the list of
actions, the list of format types and the actual data to be dropped:
bind .text_drag_source <<DragInitCmd>> \
{list {copy move} DND_Text {Hello from Tk!}}
Please note that all specified format types must be compatible to each
other, as they all characterise the same data.
SPECIFYING DRAG SOURCES WITH MULTIPLE DATA TYPES
In the case the drag source wants to send a set of (incompatible) data
types, the result of the <<DragInitCmd>> event binding must be slightly
different, as it must return two items (instead of three described in
the previous paragraph). The first element is again a list of allow‐
able actions. However, the second item is a list of "format type" and
"data" pairs: bind .text_drag_source <<DragInitCmd>> \
{list {copy move} {DND_Text {Hello from Tk!} DND_Files {/tmp}}}
And that was all!
BUGS
Unix: Dragging from Tk windows has not yet been implemented. OS X:
TkDND under OS X is built on top of the Cocoa framework. Thus, it is
compatible with Tk version >= 8.6
KEYWORDS
dnd, drag and drop
Tk 8.4 TkDND(n)