Documentation: Drag-And-Drop Functional Specification
| Document Ref: | 1309,419/FS |
|---|---|
| Project: | Shared Source RISC OS release (formerly Ursula and Java 1.2) |
| Revision: | F *** DRAFT *** |
| Date: | 16 October 2007 |
| Author(s): | Ben Avison |
Overview
This Document
This document supersedes the cut-and-paste and drag-and-drop protocol application notes [1] and [2], and specifies the cut-and-paste / drag-and-drop abilities to be added to the Wimp, plus the Clipboard module that supports the Wimp (and whose facilities will also be of use to future applications intended to support the protocols). Key terms are defined and some familiar terms are also redefined more precisely in the glossary (§13), and the reader is recommended to read this first. Where information is fundamentally new in this specification - non-obvious consequences of and clarifications and extensions to the existing protocol, the relevant section is underlined to bring attention to the fact. The document may be slightly weighted towards text-handling applications, but this is because the user interface is generally more complicated in such cases. It is expected that the reader be able to extrapolate meanings to apply to any possible fundamental type of data.Cut-and-Paste
Global-clipboard-based or cut-and-paste data transfer involves data being removed or copied from any document in the desktop to a notional "clipboard", then pasted from the clipboard into the same document, or any other document in the desktop, whether managed by the same application or not. On the way, data translation is performed in such a way as to minimise the information loss about the data. This interface involves three operations, cut, copy and paste, which may be performed in any order. Any one data transfer will require at least two of these operations, in addition to the choice of the original selection and the destination point; the process is somewhat clumsy (and unintuitive, since the clipboard is hidden from view), so this is the least preferred technique of the two described in this document. However, it must still be provided, as it does allow some operations which cannot be achieved in any other way, and can perform other operations faster than by drag-and-drop.Drag-and-Drop
Drag-and-drop is similar to cut-and-paste, but with the cut/copy performed by pressing a mouse button, and the paste by releasing the button at the destination. Full drag-and-drop compliance combines the features of conventional, simple drag-and-drop, as commonly used in Save dialogue boxes, with the data translation abilities of the global clipboard, and overcomes the abstract nature of the global clipboard by the displaying throughout the drag a bounding box, dithered sprite/object or representation of the insertion point. The user interface is simpler to use - consisting typically of two mouse drags (one to select and one to move or copy), with a requirement for at most one keypress (the Shift key swaps the meaning of copying and moving). However, the programming interface is more complicated, because continuously negotiated transferable data types, destination positioning and rendering of objects and pointers are required in addition to everything needed for cut-and-paste. This complexity is possibly responsible for the low implementation rate of the protocol to date.General
The Clipboard module is primarily to enable cut-and-paste and drag-and-drop to be reliably implemented for writable icons, which are handled automatically by the Wimp. (The fundamental problem is that the established cut-and-paste and drag-and-drop systems are Wimp-message-based, and the Wimp itself is poorly equipped to send and receive messages.) However, the module is secondarily to handle the complex protocols on behalf of any application that chooses to do so - and in the process, producing a more uniform user interface. This is to be the preferred method of implementing the protocols in future, although in special cases, the tasks it performs can be split into four separate areas, any combination of which can be taken advantage of by the same application:- clipboard management - supporting cut and copy operations
- clipboard procurement - supporting paste operations
- sending drag-and-drop data
- receiving drag-and-drop data
Outstanding Issues
Bounding Box Discrepancies
It is possible that data may have different "real life" bounding boxes in different data types - for example, a DrawFile sprite object may be transformed and/or scaled, and thus have a different bounding box to the underlying sprite. Thus if a transformed sprite object were dragged from Draw to a sprite editor window, the bounding box would not represent the final position of the sprite.Technical Background
This Document
Some important pre-existing technical terms are rigorously defined in the context of cut-and-paste / drag-and-drop in the Glossary in §13, along with some new terms introduced in this document. Where technical background information is relatively straightforward (no more than one or two short paragraphs), it is included alongside the appropriate part of §4 or §5, for ease of reference.Previous Documents
Simple drag-and-drop operations, such as those employed by Save dialogue boxes, do not employ any inter-task negotiation during the drag, and use the plain DataSave/DataLoad protocol during the drop, as described in the Programmer's Reference Manual [3]. The Style Guide [4] first indicates selection models, then describes an overview of cut-and-paste and drag-and-drop behaviour, before referring the reader to the relevant Support Group Application Notes [1] and [2].Previous Applications
Old-style selection model / copy-and-move implementations are still in existence, especially so in the case of text editors, (e.g. Zap, StrongEd, SrcEdit) which have often followed Edit's example. Such schemes typically involve only three actions to perform an operation (select region, position caret, move/copy keypress) rather than the four (select region, cut/copy keypress, position caret, paste keypress), but have the disadvantage that they can present both a caret and a selection to the user at the same time, which is potentially confusing. Old behaviour will remain deprecated, but new cut-and-paste / drag-and-drop applications must be able to interact with tasks that use it. Other applications may support just cut-and-paste, or just drag-and-drop. Drag-and-drop will be the favoured technique in future, due to the simpler actions required (select region, drag region), but cut-and-paste must also be supported as well, to cater for cases when drag-and-drop cannot be used (e.g. when copying on to a menu tree). Some aspects (e.g. pointer shape, window) of applications already written to the application note guidelines (e.g. DataPower, EasiWriter/TechWriter) are already inconsistent, due to the lack of detail in the application notes. Applications will in future be encouraged to follow the more detailed specification herein.User Interface
Selection
Protocol
Rendering
Selection is rendered either by a recolouring an object (with its photographic negative or otherwise) or by drawing a bounding box, typically in red, and optionally with one or more "handles" for resizing and/or rotating operations as appropriate:



Mouse Events
Non-contiguous selections (just about everything except text and DTP documents) will continue to be handled as described in the Style Guide [4], with the proviso that clicking Select over an already-selected object must not deselect anything, as a Select click event always precedes the Select drag event which initiates a drag-and-drop operation. Appropriate action must also be taken to un-shade shaded selections when necessary. On the other hand, a more detailed behaviour for contiguous selections must be adhered to in future. In summary:- Select click outside the selection (or when there is no selection, or at one end of a selection): position the caret at the pointer position, and flag the next Select drag as creating a selection.
- Select click on a selection: if the selection was shaded, un-shade it. Make sure the window has the input focus. Flag the next Select drag as being a drag-and-drop drag.
- Select click in a "dead" region of a window (e.g. in a page border): un-shade any selection or replace any shadow caret with the caret, if either exists. Make sure the window has the input focus. Optionally, flag the next Select drag as causing an window scroll operation (as Impression, TechWriter etc. do as present), but certainly not as starting a selection or drag-and-drop operation.
- Select drag-start event: remove the caret, and set the selection from the old caret position to the current pointer position. Alternatively, start the drag-and-drop operation (see §4.4.1). The exact meaning is determined by the flag that was set at the Select click stage.
- During Select drag: if creating a selection, adjust the most recently touched end of the selection to the pointer position at regular intervals; autoscroll the window if necessary, using the SWI Wimp_AutoScroll introduced in the RISC OS 4 Wimp. For what to do during a drag-and-drop drag, see §4.4.1.
- Select double-click: select a word (as defined in the Style Guide), irrespective of whether the click is on an existing selection or not.
- Select click-drag (button pressed, then released, then pressed again within the double-click limits, then held or moved according to the drag limits): equivalent to a normal selection-delimiting drag, except that the selection limits are rounded to word boundaries (excluding whitespace at either end).
- Adjust click when there is no caret or selection: position the caret at the pointer position, unless there was a shadow caret, in which case, position the caret where the shadow caret was. Set a flag to indicate that there was no caret or selection before the Adjust click (the shadow caret doesn't count); do not rely on the fact that there is no selection displayed when the drag event is generated to flag this, as a zero-width selection may have been displayed as a caret instead.
- Adjust click when there is a caret: remove the caret, and set the selection from the old caret position to the current pointer position.
- Adjust click when there is a selection: grow or shrink the selection so that the nearest end of the selection moves to the pointer position. (Remember to un-shade the selection and/or gain the input focus if necessary.)
- Adjust click in a "dead" region of a window: the same as Select in these circumstances.
- Adjust drag-start event: unless there was no caret or selection before the preceding Adjust click, adjust the most recently touched end of the selection to the pointer position.
- During Adjust drag: unless there was no caret or selection before the preceding Adjust click, adjust the most recently touched end of the selection to the pointer position at regular intervals; autoscroll the window if necessary, using SWI Wimp_AutoScroll.
Keypresses
There are some special keypresses relating to cut-and-paste that affect the selection. Obviously, these only apply to selections that have the input focus (and therefore never apply to a shaded selection). The keypresses are:- Ctrl-Z: clear the selection (i.e. undraw the highlights), and place the caret (if appropriate) at the right-hand end of the old selection (or the left-hand end in a right-to-left language).
- Ctrl-V or Insert: delete (not cut) the selected data, and place the caret (if appropriate) at the end of the newly inserted text.
- Ctrl-X, Backspace or Delete: cut the selected data and place the caret (if appropriate) where the selection was.
- Ctrl-K: delete (not cut) the selected data and place the caret (if appropriate) where the selection was.
Then there are a number of special behaviours for textual regions:
- Left-arrow/up-arrow: clear the selection, and process the keypress as though the caret had been at the left of the selection.
- Right-arrow/down-arrow: clear the selection, and process the keypress as though the caret had been at the right of the selection.
- Any other repositioning keypresses (Home, Tab etc.) behave along similar lines, as appropriate to the application.
- Any other keypresses that would normally insert one or more characters: perform a cut operation, then position the caret where the selection was, and process the keypress as normal.
Any other keypresses must not affect the selection. During drags (both those that set a selection and those that copy or move one), no keypresses that would normally affect the selection must be acted upon.
Scope
When a caret or selection is placed in the same window where one already exists, the old one is removed (not just re-rendered as a shaded selection). In order for this to be consistent with the use of input focus colouring of windows, all carets and selections must be unique within a group of windows characterised thus: a top-level (non-nested) window, all its panes, and all windows nested within the window or one of its panes. If a task does its own selection handling but the window or one of its panes also uses writable icons, the task will need to monitor caret/selection updates to the writable icons in order to deselect its own selections. Carets and selections must not be preserved when a window is closed, deleted or iconized (check for Open_Window_Requests with handle-to-open-behind of -3 to detect iconization). The Wimp takes care of everything for Wimp-drawn carets, and automatically removes the input focus in any case. If a selection can be made in a dialogue box opened from a menu, then the task must act as though the window were being closed when receiving Message_MenusDeleted, as tasks are not sent the usual Close_Window_Request for such windows. When the window is being closed or deleted, application-drawn carets and selections must be marked as absent, but when it the window is being iconized, carets and selections drawn by the application must be flagged as a shadow caret (if supported) or a shaded selection, respectively, ready for the next redraw request.Clipboard Module
The Clipboard is not involved in the selection process.Writable Icons
Up to one writable icon selection may exist in each window, and the selection will only be un-shaded if the window has the input focus.Rendering
Carets within writable icons will be Wimp colour 11 (red), irrespective of the background colour of the icon. This will be achieved by using (Wimp colour 11 EOR background colour), calculated in GCOL space, as the colour to EOR on to the icon. Selections and shaded selections will be drawn by switching the foreground and background colours, then fading them if appropriate. A gap of 4 OS units will be left before the top and bottom borders (if any) of the icon. Therefore, a typical writable icon will look like this in its three states:
Scrolling
Icons where the text is less wide than the icon are relatively simple; the text has a fixed position, irrespective of caret and selection position. But it is likely that where the text is wider than the icon, occasions will arise where the user needs access to areas of the text string that are normally hidden, in order to set one or both ends of a selection. The matter is similar to the requirement for icon scrolling to position the ghost caret during a drag-and-drop selection (see §4.4). So, while the user is delimiting a selection, or when a ghost caret is displayed in the icon, an autoscrolling scheme will be followed, directly analogous to that used for windows in Wimp_AutoScroll. Note in particular:- The speed of scrolling is proportional to the distance the pointer has moved beyond the inside edge of the autoscrolling "pause" zone. This is because this scheme allows fine user control of both acceleration and deceleration.
- When delimiting a selection, autoscrolling will start as soon as the pointer enters the "pause" zone - i.e. a pause time of zero is used. Conversely, to start autoscrolling during a drag-and-drop operation, the pointer must be held over the pause zone for the configured pause time. This matches the equivalent behaviour for autoscrolling of windows.
- While document windows are generally of a comparable size, hence the similar pause zone widths, the size of writable icons can vary dramatically from icon to icon - compare, for example, a writable icon that is part of a numeric field, with the URL at the top of a web browser window. Scrolling speeds that would suit a small icon would be painfully slow for a very large one, and usable speeds for a large icon would scroll a small icon far too quickly. Therefore, the scrolling speed of a writable icon when the pointer is at one end will be proportional to its width. However, it is also desirable that the scrolling speed ramp up at the same rate, irrespective of icon size; these two constraints imply that a fixed proportion of the width of any icon needs to be allocated as the autoscroll pause zone - we will use 1/4 of the width at each end, as illustrated to scale below:
Below, the autoscrolling zone is cross-hatched; the autoscrolling pause zone is the intersection of the autoscrolling zone with the icon bounding box:
Mouse Events
Mouse events in writable icons will follow the general behaviour, as specified in §4.1.1.2, but with a couple of slight changes. The definition of a word will match that used for Shift-arrow navigation, i.e. treating both spaces and the '.' character as word delimiters. On the second click of a double click with Adjust, the selection established by the first Adjust click will be extended outwards at both ends to include complete words. Clicks with either Select or Adjust will not affect the text origin, unless they are setting the caret position (which will still be centred as far as possible, for consistency with old Wimps). Neither double-click operation will affect the text origin either, unless a scroll was caused by the first click of the two. During a drag, while the pointer is over the central zone between the autoscrolling zones, no scrolling occurs. The autoscrolling zones act just like those of windows. After each scroll step (not before), the selection end is determined by the closest character boundary to the pointer. When a drag starts, any movement of the text which was performed at the time of the click event is undone. This is necessary because otherwise we have introduced a relative movement between the text and the pointer which was not intended by the user, and the alternative (moving the pointer) is less in the style of the RISC OS user interface. Consider, for example, if the user clicks Select at the right hand end of an icon where there is a lot of text further to the right which is clipped out of view: if the user starts dragging to the left, but as a result of the initial click, the text had jumped quickly to the left of the pointer and so the user is now creating a selection to its right; worse still, if the pointer is still over the autoscrolling zone, the initial character may start scrolling off the left of the icon, leaving a large selection in the opposite direction to that intended by the user!Keypresses
These will in general be handled as in §4.1.1.3. Note in particular:- Only keypresses as specified in the validation string would normally insert characters, so any others (except Ctrl-X and its synonyms, of course) will not cut any selected text.
- Whenever a keypress (including Ctrl-X and synonyms) causes the caret to be repositioned, a traditional, centred caret will be used.
- When a paste is performed, and so an entirely new selection is set, the selection will be centred within the icon (unless it is wider than the icon, in which it will be right-aligned).
Wimp Selections and Menus
When the pointer moves over a writable menu item, or when a dialogue box containing writable icons is opened from a menu, the Wimp automatically places the caret in the menu item, or the first writable icon, respectively. The Wimp remembers the position of the caret before it does this, and then returns the caret to its old location afterwards. This behaviour will be extended to check for Wimp selections that have the input focus before the caret is placed. If the same selection still exists afterwards (i.e. a selection has not been made within the menu structure in the meantime), then the input focus will be returned to it. Note that selections cannot be made in writable menu items, as any clicks are considered as choices from the menu tree before being considered as requests to set the caret position, let alone setting a selection. Also note that drags cannot be made to an icon in a menu structure, as the click that starts the drag will close the menu structure before the drag begins! Cut and paste will work as specified for writable icons in dialogue boxes in menu trees, and pasting (but obviously not cut or copy) will work for writable menu items.Password icons
Cutting, copying and dragging from a password icon, or pasting or dragging into one, is not permitted for security reasons. To give the user some feedback, the Wimp issues a system beep if the user attempts to do so. Selecting text in a password icon is permitted, although the only action that can be performed on it is deletion.Application-altered Indirected Data
On occasions, the text of a writable icon is altered by code other than the Wimp's writable icon handling code (and as a prerequisite, the text data has to be indirected). A common example of this is the writable numeric range, where adjuster arrows may be used to alter the value inside the accompanying writable icon. Altering the data does not, in itself, cause any screen updates to be done; applications have to force a redraw of the icon for the new value to be displayed. During the redraw, the caret is redrawn, but only using the last work-area-origin-relative co-ordinates calculated the last time the caret was positioned. If the new data requires a different text origin, the caret will then appear incorrectly positioned. To cater for this, nearly if not all applications set the position of the caret again, as well as forcing a redraw of the icon. A similar situation could arise with selections (and even ghost carets) - but since no existing applications know about selections, they will not be able to cater for the "feature" in the API. For example, suppose the value 99 was selected in a centred numeric range, then the up-arrow was pressed; the result would be as below:
Scope
In addition to the rules in §4.1.1.4., any combination of caret, ghost caret and selection must be removed when an icon is deleted. Also, when a menu is closed, any selection in a dialogue box linked to the menu must be removed (the caret already is removed in these cases). It will not be possible for any caret, selection or ghost caret to be placed in a writable icon that is shaded. If any caret, selection or ghost caret is present in a writable icon when it becomes shaded, they will be removed. The Wimp selection and both carets will be removed when the Wimp font is changed, but this will be the responsibility of the task that is changing the font - namely !Configure (or more precisely, a configure plug-in). If an icon is resized using Wimp_ResizeIcon, any of the caret, ghost caret and selection which are present in the icon will be marked absent (although no redrawing will occur immediately, because Wimp_ResizeIcon expects to be followed by a separate redraw operation anyway).Draggable-Writable (Type 14) Icons
Type 14 (draggable) writable icons are much rarer than standard, type 15 writable icons, and in the past, have only differed in that drag events are reported to the task. Some applications (such as Fresco) have taken advantage of these icons to implement a simpler form of drag-and-drop; such behaviour would be broken if the steps described above were employed for type 14 icons. Type 14 icons could also be a useful special case, where sub-units of the information in the icon have no meaning on their own, and where only the entire text can logically be dragged-and-dropped. Therefore, all of the rest of §4.x.3 and §5.x.3 (with the exception of developments specific to carets, such as the bugfix in §4.1.3.7) will only apply to type 15 writable icons.Cut and Copy
Protocol
"Cut" and "Copy" menu options, if provided, must be placed as described in the Style Guide; the options must be shaded if there is currently no selection in the window. A cut operation must be performed when the task receives a Ctrl-X, Backspace or Delete keypress (i.e. Wimp key codes &008, &018 and &07F) or when "Cut" is chosen from the menu. When a keypress suitable for inserting data is received, or when data is dragged-and-dropped on to the selection's window, or pasted when a selection is active, the selection must also be cut prior to performing the raw operation. A copy operation must be performed when "Copy" is chosen from the menu, or when the task receives a Ctrl-C keypress (Wimp key code &003) - but not when Wimp key code &18B is received, because although it resulted from a press of the "Copy" key on the Archimedes, A30x0, A4000 and A5000, on all other machines it will be generated by the "End" key. Both cut and copy will cause a copy of the selected data to be placed on the clipboard overwriting any data already there. (See §13 for a definition of clipboard in this context.) No attempt must be made to render the clipboard; it is a hidden, abstract entity. The data on the clipboard is of indeterminate data type; a data type to use for the transfer is negotiated between the clipboard owner and the pasting task at paste-time, and may involve either or both tasks performing data translation. The only difference between cut and copy is that the selected data must be removed from the main document in the case of a cut operation. The selection remains unchanged in the case of a copy operation (i.e. it is not deselected). If the data cut or copied to the clipboard is of type text, the newlines (if any) must be represented by ASCII &0A.Clipboard Module
The use, or not, of the Clipboard module to handle cut and copy operations will not affect the cut or copy user interfaces, even though this entails some complication of the programming interface (see §5.2.2).Writable Icons
Keypresses will be honoured as described in §4.2.1 - although individual icons don't and shouldn't have menus, so the description of performing cuts and copies via a menu is inappropriate. The data held in the writable icon will always be plain text, and the exported data can only be the same, so management of the clipboard can and will be delegated to the Clipboard (and as a consequence of this, a Message_ClaimEntity 4 will be issued by the Clipboard every time data is cut or copied to the clipboard from a writable icon, including those in menu structures).Paste
Protocol
A"Paste" menu option, if provided, must be placed as described in the Style Guide; the option must be shaded if there is no data on the clipboard suitable for pasting into the document, even though this may entail a slight delay before opening of the submenu while the application interrogates the current owner of the clipboard. The keypresses Ctrl-V and Insert (Wimp key codes &016 and &1CD) are both equivalent to choosing "Paste" from the menu. If there is a selection present in the window before the paste operation, it must be deleted before the paste takes place; swapping the clipboard contents and the selection would prevent the same data being pasted multiple times. The new data is inserted at the caret, or where the old selection was positioned, and the pasted data is automatically selected, so that the user can immediately cut it again, should it be so desired. If the data pasted from the clipboard is of type text, any instances of ASCII &0A, &0D, or both codes adjacently in either order must be treated equally, as a single newline.Clipboard Module
The use, or not, of the Clipboard module to handle paste operations will not affect the paste user interface.Writable Icons
Keypresses will be honoured as described in §4.3.1 - although individual icons don't and shouldn't have menus, so the description of performing pastes via a menu is inappropriate. Handling the protocol for obtaining the pasted data will be delegated to the Clipboard. Pasted data must be available in text (data type &FFF) form, or else the keypress will be ignored. Only text up to the first instance of ASCII &00, &0A or &0D, or the length of the spare space in the data buffer (plus the length of any selection), will be considered; if this string contains other control characters, or characters forbidden by the validation string, the operation will be faulted with a beep. In this case, no characters are inserted and any pre-existing selection is neither deselected nor deleted.Drag
Protocol
General
When the user starts a drag-and-drop drag (which will always be with the Select button, at least for text selections), the selection is not deselected. When the drag ends, the new data is selected, which means that, unless the drag was a move operation, or the destination is in the same window as the source, the old selection will subsequently be redrawn as a shaded selection. If, during any drag operation, the Escape key is pressed, the drag must be aborted. Any other keypresses during a drag must be ignored (except of course for the status of the Shift key at the beginning of the drag, which is responsible for exchanging the meanings of copy and move operations).Pointers
During a drag, the pointer shape is changed to the new standard alternative pointer shape ptr_drop; this must be used instead of the alternatives employed by DataPower, TechWriter and others. The new pointer shape will be added to the Wimp's RAM sprite pool by the Clipboard module, so that it is always available for tasks to use.
Dragboxes
Linked to the pointer position, there will be at all times during the drag either a representation of the (potential) drop position, or of the original data, but not both. Which is used depends on both the sending and (potentially-) receiving tasks, and on the type of data being dragged: if the receiving task understands at least one of the the data types, it will draw the drop position; if not, the sending task is responsible for the representation of the original data. The representation of the original data, when required, can take the form of either a rotating-dash Wimp box of the same size as the original selection, or of a DragASprite or DragAnObject rendering. As ever, if the CMOS indicates as such, a dragbox must be used instead of a DragASprite or DragAnObject drag. If a selection consisting of multiple, non-contiguous objects is to be represented without using a dragbox, the Wimp sprite "package" must be used, to match the Filer's behaviour.

Ghost Carets
The representation of the drop position - known as the ghost caret - has two typical forms. When the pointer is over a primarily textual region, and the task understands at least one of the available data types, the ghost caret can be displayed as a grey I-beam, "snapped" to the nearest character boundary. When the pointer is over a layout-based region, a grey bounding box, scaled according to the zoom setting of the window, can be displayed, snapped to any grid, guidelines, frame boundaries etc. as appropriate. The two are not necessarily mutually exclusive; a DTP package might, for example, want to display an I-beam when underneath a text drag, but a scaled bounding box when underneath a sprite drag. If neither form is appropriate, and the application knows of no other appropriate rendering either, the sending task must be informed (or be allowed to continue) to display the dragbox, sprite or whatever.

Scrolling
During a drag, when the pointer is over a window that can scroll, autoscrolling must be turned on using the SWI Wimp_AutoScroll. For more details of the effect of this SWI, see [5], but note that unless the pointer is held still near the edge of the window for a period, no scrolling will occur. Since determination of the pause zone is dependent upon positioning of panes etc., the activation and deactivation of Wimp_AutoScroll is the responsibility of the receiving task.Clipboard Module
The use, or not, of the Clipboard module to handle drag operations will not affect the drag user interface.Writable Icons
Drags from writable icons will use the ptr_drop pointer, and a rotating-dash dragbox matched in size to the selection. If the pointer has not moved since the click, the drag will initially look like this (with the dashes rotating):
Drop
Protocol
Sending
When a drag-and-drop drag ends, the sending task attempts to transfer data to the task under the pointer, or if a drag-and-drop dialogue was in effect, to the receiving task (which can only be different from the task under the pointer if the receiving task is autoscrolling one of its windows). The data type actually transferred is negotiated between the sending and receiving tasks at the time of the drop; it may entail either or both tasks performing data translation. The decision whether to delete the original data when the drag ends (i.e. whether to copy or move the selection) is based upon the state of the Shift key when the drag began, and upon whether the pointer position at the end of the drag is in the same window as at the start, or not. Drags within a window move the data unless Shift is held down; drags between windows copy the data unless Shift is held down. Shift reverses the meaning of the drag, so within a region, the selection is copied, and between regions, the selection is moved. The destination task can also insist that the operation be a move irrespective of the above; this is to allow for trashcan applications. Drags to non-drag-and-drop applications (including the Filer) are treated the same as drags to a different window. In some circumstances, such as dropping data onto a directory viewer, the filename used in the data transfer protocols will become visible to the user. For these to be meaningful to the user, these filenames should follow the convention of concatenating the source of the data with the textual filetype, for example "IconText" or "PaintSprite". When generating data of type text that includes newline characters, you must use ASCII &0A to terminate lines.Receiving
To the destination task, a drop will appear the same as a non-drag-and-drop DataSave (inter-application data transfer) operation, except that the Wimp message is subtly marked (by virtue of having a non-zero your_ref field) as having resulted from previous messaging (i.e. the drag-and-drop dialogue). Assuming the task doesn't reject the data as being unsuitable, this is sufficient for the task to know what to do with the data: If a drag-and-drop drop,- If a ghost caret was being displayed, the insertion point is set to the last known ghost caret position.
- Otherwise, the insertion point is set to the position specified in the message (i.e. the pointer position), snapped if necessary.
If a non-drag-and-drop drop,
- If a caret (shadow or not) or selection (shaded or not) is being displayed, the insertion point is set there.
- Otherwise, the insertion point is set to the position specified in the message, snapped if necessary.
If the insertion point thus determined lies on a selection (shaded or not), the said selection must be cut to the clipboard. (This is the only circumstance in which the clipboard is affected by a drag-and-drop operation.) The new data is inserted, and is then selected itself. If the insertion point lies on the source selection, no actions must be taken. The selection remains selected. Received text data must be correctly handled whether newlines (if any) are indicated using ASCII &0A, &0D, or both characters in either order.
Clipboard Module
The use, or not, of the Clipboard module to handle drop operations will not affect the drop user interface.Writable Icons
The requirements for acceptance of dropped data are the same as for pasted data (see §4.3.3). Text dragged from a writable icon is not terminated in any way - the "file" length determines the amount of text. The leafname used for icon-sourced text will be "IconText"; because the data transfer message handling will be delegated to the Clipboard, there will be no opportunity to change the leafname so as not to overwrite an existing file of the same name.Programming Interface and Data Interchange
These two sections have been combined because any programming interfaces being specified are intimately connected to data interchange, and it makes no sense to discuss the programming interfaces before the data interchange they relate to.Selection
Protocol
Handling mouse and key events relating to and rendering of selections is the responsibility of the task. The task may use Wimp_SetCaretPosition to delegate drawing of the caret, but non-I-beam carets and selections need to be drawn during window update and redraw code. To give a window the input focus without displaying the Wimp caret (for example, when setting a selection), Wimp_SetCaretPosition must be called with R4 bit 25 set. Whenever a cut-and-paste / drag-and-drop task gains either the caret or the selection, it must broadcast the following event 17 Wimp message with both flag bits 0 and 1 set:| Message_ClaimEntity (&0000F) | |||||
| This message is broadcast by a task claiming the cut-and-paste / drag-and-drop caret, selection or clipboard. | |||||
| R1+12 | your_ref: 0 | ||||
| R1+20 | flags: | bit 0/1 set | => | caret or selection being claimed | |
| bit 2 set | => | clipboard being claimed (see §5.2.1) | |||
| all other bits are reserved and must be clear | |||||
Clipboard Module
The Clipboard is not involved in the selection process. However, any programs planning to rely entirely on the Clipboard to manage its cut-and-paste / drag-and-drop data transfer must still claim the caret and selection as described in §5.1.1.Writable Icons
Wimp_SetCaretPosition API
Wimp_SetCaretPosition will be extended to allow the following entities to be created:- Carets in writable icons that are not necessarily centred when the text is wider than the icon.
- "User" ghost carets - i.e. ghost carets not in an icon. *
- Ghost carets in writable icons (not necessarily centred). (See §5.4.3.)
- Selections in writable icons, centred when the text is wider than the icon. *
- Selections in writable icons, not necessarily centred when the text is wider than the icon.
Those entities above marked with an asterisk will also be made available to tasks. Any calls using the API for the others will be ignored, unless called using the internal Wimp routine. Below is the complete new Wimp_SetCaretPosition API, including the existing functionality, in a more digestible form than in the RISC OS 3 PRM. This includes the calls for internal use only; although these are internally distinguished by flags bit 28 being set, as far as the outside world is concerned, both bits 28 and 29 remain "reserved, must be zero".
| Wimp_SetCaretPosition (SWI &400D2) | ||||
| Set up the data for a new caret, ghost caret or selection position, and redraw it there. | ||||
| On entry | ||||
| To remove the caret / ghost caret / selection: | ||||
| R0 = | -1 | |||
| R2 = | "TASK" => | use bits 30 and 31 of R4 to determine which entity to remove, otherwise remove the caret | ||
| R3 = | flags | bits other than 30 and 31 reserved, must be zero | ||
To set a user caret / user ghost caret: | ||||
| R0 = | window handle | |||
| R1 = | -1 | |||
| R2 = | x-offset of caret / ghost caret, relative to work area origin | |||
| R3 = | y-offset of caret / ghost caret, relative to work area origin | |||
| R4 = | height of caret, and flags | |||
To set an icon caret, centred if possible, by known index into the string: | ||||
| R0 = | window handle | |||
| R1 = | icon handle | |||
| R4 = | -1 | |||
| R5 = | index of caret into string (must be >= 0) | |||
| or alternatively, if you wish to override the default Y position, size or flags: | ||||
| R0 = | window handle | |||
| R1 = | icon handle | |||
| R3 = | y-offset of caret, relative to work area origin | |||
| R4 = | height of caret, and flags (bits 28-31 all clear) | |||
| R5 = | index of caret into string (must be >= 0) | |||
To set an icon caret, centred if possible, by approximate current position on screen (note that if positioning the caret there causes the icon to scroll, the final caret position may be very different to the specified position): | ||||
| R0 = | window handle | |||
| R1 = | icon handle | |||
| R2 = | current x-offset of desired position, relative to work area origin | |||
| R3 = | current y-offset of desired position, relative to work area origin | |||
| R5 = | -1 | |||
To set an icon caret / icon ghost caret, not necessarily centred: * | ||||
| R0 = | window handle | |||
| R1 = | icon handle | |||
| R2 = | new value of caret scrollx | |||
| R3 = | 0 (reserved for future expansion) | |||
| R4 = | height of caret, and flags (bit 28 set, bit 30 set for ghost caret or clear for caret, bit 31 clear) | |||
| R5 = | index of caret into string (must be >= 0) | |||
To set an icon selection, centred if possible (or if the selection is wider than the icon, right-aligned within the icon): | ||||
| R0 = | window handle | |||
| R1 = | icon handle | |||
| R4 = | flags (bit 28 clear, bit 30 clear, bit 31 set) | |||
| R5 = | index of lower boundary into string | |||
| R6 = | index of upper boundary into string (no action is taken if R5 >= R6) | |||
To set an icon selection, not necessarily centred: * | ||||
| R0 = | window handle | |||
| R1 = | icon handle | |||
| R2 = | new value of selection scrollx | |||
| R3 = | 0 (reserved for future expansion) | |||
| R4 = | flags (bit 28 set, bit 30 clear, bit 31 set) | |||
| R5 = | index of lower boundary into string | |||
| R6 = | index of upper boundary into string (no action is taken if R5 >= R6) | |||
Flag bits 30/31 determine which entity the call refers to, and also affect the other flag bit meanings: | ||||
| Value | Entity | Bit(s) | Meaning (if one bit, then meaning when set) | |
| 0 | Caret | 0-15 | height in OS units (0-65535) | |
| 16-23 | colour (bits 20-23 ignored if a Wimp colour number) | |||
| 24 | use a Wimp-drawn caret rather than the Font Manager caret | |||
| 25 | do not draw the I-beam (caret is invisible) | |||
| 26 | use bits 16-23 for colour (else defaults to colour 11) | |||
| 27 | colour is a GCOL, otherwise a Wimp colour number | |||
| 28 | use both R2 and R5 to position the caret in an icon and override centring behaviour (internal use only, must be zero for external callers) | |||
| 29 | reserved, must be zero | |||
| 1 | Ghost caret | 0-15 | height in OS units (0-65535) | |
| 16-23 | not used; must be zero (palette entry &80808000 always used) | |||
| 24 | use a Wimp-drawn caret rather than the Font Manager caret | |||
| 25-27 | not used; must be zero (cannot be invisible, colour is fixed) | |||
| 28 | use both R2 and R5 to position the ghost caret in an icon and override centring behaviour (internal use only, must be zero for external callers) | |||
| 29 | reserved, must be zero | |||
| 2 | Selection | 0-25 | not used; must be zero (height and colour determined by icon properties and bit 26) | |
| 26 | use shaded selection colour scheme (also implies that the window containing the selection should not be awarded the input focus as the result of this call) | |||
| 27 | the window containing the selection should not be awarded the input focus, even if it is not shaded | |||
| 28 | use both R2 and R5/R6 to position the selection in an icon and override centring behaviour (internal use only, must be zero for external callers) | |||
| 29 | reserved, must be zero | |||
| 3 | Reserved | |||
| On exit | ||||
| R0-R5 are preserved, except that if R0 was -1 and R2 was "TASK" on entry, then R2 is set to zero on exit. | ||||
| The versions of the indexes into the string held internally, after an icon caret is positioned by index, will in future be restricted to the range { 0 <= index <= length } rather than just { index >= 0 }. This is essentially a bugfix, and will affect the values returned by Wimp_GetCaretPosition. | ||||
Wimp_GetCaretPosition API
The complimentary SWI will be extended to allow for Wimp_SetCaretPosition's new functionality:| Wimp_GetCaretPosition (SWI &400D3) | ||||
| Returns details of the state of the caret, ghost caret or writable icon selection. | ||||
| On entry | ||||
| R0 = | if R2 = "TASK", this is the entity to inspect (0 => caret, 1 => ghost caret, 2 => selection) | |||
| R1 -> | block to fill with entity state | |||
| R2 = | "TASK" => | fill block with state of entity specified by R0 and R3, else fill block with caret state | ||
| R3 = | if R0 = 2 and R2 = "TASK", this is either the handle of the window to inspect, or -1 to inspect the window which currently has the input focus and therefore also the only un-shaded selection | |||
| On exit | ||||
| R0 | corrupted | |||
| R1 | preserved | |||
| R2 = | 0 if it was "TASK" on entry | |||
| R3 | preserved | |||
If the caret or ghost caret state is being returned, the block is filled as follows: | ||||
| R1+0 | window handle (or -1 if there is no [ghost] caret) | |||
| R1+4 | icon handle (or -1 if a user [ghost] caret) | |||
| R1+8 | x-offset of [ghost] caret, relative to work area origin | |||
| R1+12 | y-offset of [ghost] caret, relative to work area origin | |||
| R1+16 | height of [ghost] caret and flags (bit 28 clear) | |||
| R1+20 | index of [ghost] caret into string (undefined if a user [ghost] caret) | |||
If the selection state is being returned, the block is filled as follows: | ||||
| R1+0 | window handle (or -1 if there is no writable icon selection) | |||
| R1+4 | icon handle (>= 0) | |||
| R1+8 | x-offset of lower boundary of selection, relative to work area origin | |||
| R1+12 | width of selection | |||
| R1+16 | y-offset of selection, relative to work area origin | |||
| R1+20 | height of selection and flags (bit 28 clear) | |||
| R1+24 | index of lower boundary into string | |||
| R1+28 | index of upper boundary into string | |||
Cut and Copy
Protocol
When a cut or copy operation is requested of an application, it must copy the selected data to the clipboard. Under the raw protocol, each task is responsible for allocating (and deallocating) the memory necessary to store the clipboard. The clipboard must hold the data in a form from which it can be translated to the maximum number of other data types, which usually means it must be held in the application's internal format. In order to ensure that only one clipboard is active globally at a time, it is necessary that when a cut or copy operation is performed, the cutting/copying task broadcasts a Message_ClaimEntity (see §5.1.1) with bit 2 set. Accordingly, when a task receives such a message, it must deallocate the memory used to store its own clipboard (unless of course, its own clipboard was not in use). The message must not be sent if the same task already owned the clipboard.Clipboard Module
One of the Clipboard's functions is to allocate and manage memory to store the clipboard data for any participating tasks, following a cut or copy operation. However, the Clipboard has no intrinsic knowledge of how to translate data between different formats, so it is essential that no task uses the Clipboard for this purpose if it is able to translate data on export. For example, none of Edit, Paint or Draw can exclusively use the Clipboard for clipboard storage - Edit could export Basic programs as a tokenised file, or as text; Paint can export both sprites and palettes; and Draw can export text, sprites, JPEGs and PostScript as well as DrawFiles. Despite this, the raw protocol messaging involved at the pasting stage is still not completely trivial, and so an alternative method will be provided, whereby the task is still responsible for storing the clipboard and translating the data when required, but the Clipboard handles all the associated Wimp messaging. This also allows some code sharing with the data-send end of the drop operation.| SWI Clipboard_Put (&4E000) | |||||
| Puts data on the clipboard, or initiates the data-send of a drop (see §5.4.2). | |||||
| On entry | |||||
| R0 = | flags: | bit 0 set | => | clear the clipboard (must be used when the application exits, unless another task has since claimed the clipboard using a Message_ClaimEntity 4) | |
| bit 1 set | => | do not store the data, just the data length (and the task handle) - when the data is required, the Clipboard will send the clipboard-owning task a Message_PutRequest stating the required data type, see §5.3.2 | |||
| bit 2 set | => | R1 is a pointer to a data type list, otherwise R1 is the data type | |||
| bit 31 set | => | flag reply messages as for the attention of the Wimp | |||
| all others are reserved and must be zero | |||||
| R1 = | depending on flags bit 2, either the data type (in bits 0-11), or a pointer to non-null list of data types that the task can translate the data to (in no particular order), terminated by -1 | ||||
| R2 = | pointer to data (if flags bit 1 is clear) | ||||
| R3 = | data length | ||||
| R4 = | pointer to proposed leafname of data, null-terminated | ||||
| R5 = | my_ref of Message_PutRequest which this is a reply to, or 0 if this isn't a reply | ||||
| On exit | |||||
| R0-R5 preserved | |||||
| The Clipboard broadcasts a Message_ClaimEntity 4 (unless the Clipboard owns the clipboard already), and takes a copy of the data, the leafname and the data type list, as appropriate. An error is generated if any of the pointers are invalid. | |||||
- passing clipboard data to the Clipboard module to handle on the application's behalf
- passing enough information about the clipboard to the Clipboard so it can advertise on our behalf (or proxy) and get back to the application if and when a paste operation happens
- passing selection data to the Clipboard
Writable Icons
The Wimp itself is not a Wimp task. One of the consequences of this is that it has no task handle, and is as such not well suited to handling Wimp messages. Because of this, it will make heavy use of the Clipboard. When the user types Ctrl-C or Ctrl-X in a writable icon, the Wimp will call Clipboard_Put with all flags clear and a data type of &FFF. The data will not be terminated; only the data length word will determine the extent of the data.Paste
Protocol
The application must first check to see if it owns the clipboard, and use the data directly if so. If it does not own it, it must broadcast a Message_DataRequest (message type 18):| Message_DataRequest (&00010) | |||||
| This message is broadcast by a task when it wishes to paste data from a clipboard maintained by another task. | |||||
| R1+12 | your_ref: 0 | ||||
| R1+20 | destination window handle | ||||
| R1+24 | internal handle to indicate destination of data; may be icon handle (see below) | ||||
| R1+28 | destination x co-ordinate | ||||
| R1+32 | destination y co-ordinate | ||||
| R1+36 | flags: | bit 2 set | => | send data from clipboard | |
| all other bits are reserved and must be clear | |||||
| R1+40 | list of data types in receiver's order of preference, terminated by -1 (may be null) | ||||
Clipboard Module
The Complete Paste Process
During the paste process, the Clipboard behaves to conventional drag-and-drop tasks exactly like any other clipboard owner, and responds to Message_DataRequests as described above. It also provides an alternative interface to the pasting process, involving much less messaging. It involves SWI Clipboard_Get and the messages Message_PutRequest and Message_Paste. However, as before, if a task is managing its own clipboard, it must use the data directly in preference (although this will now only be in cases where the data can be translated on export).| SWI Clipboard_Get (&4E001) | |||||
| Requests data from the clipboard, using the Clipboard as a proxy. | |||||
| On entry | |||||
| R0 = | flags: | bit 31 set | => | flag reply messages as for the attention of the Wimp (this bit must only be set by the Wimp) | |
| all others are reserved and must be clear | |||||
| R1 = | destination window handle | ||||
| R2 = | destination icon handle (-1 if none) | ||||
| R3 = | destination x co-ordinate | ||||
| R4 = | destination y co-ordinate | ||||
| R5 = | pointer to list of data types that the task is interested in receiving, in order of preference, terminated by -1 (may be a null list if the native format is required) | ||||
| On exit | |||||
| R0-R5 preserved | |||||
| The Clipboard takes an internal copy of the data type list. If it owns the clipboard itself, it replies immediately with a Message_Paste. If a task has registered itself with the Clipboard using a bit-1-set SWI Clipboard_Put, the Clipboard sends a Message_PutRequest to the clipboard owner, and uses the data copied from the details in the following SWI Clipboard_Put to construct a Message_Paste. Alternatively, if a conventional drag-and-drop task owns the clipboard, the Clipboard will send a Message_DataRequest and handle all the Message_DataSave etc. messaging, before sending a Message_Paste to the pasting task, thus creating a uniform interface. | |||||
| Message_PutRequest (&4E000) | |||||
| This message requests that clipboard or selection data be sent to the Clipboard. | |||||
| R1+12 | your_ref: 0 | ||||
| R1+20 | flags: | bit 0 | => | flags bit 0 to use in Clipboard_Put | |
| bit 1 | => | flags bit 1 to use in Clipboard_Put | |||
| bit 2 | => | flags bit 2 to use in Clipboard_Put (note this also determines whether a single data type, or a data type list pointer is required in R3) | |||
| bit 3 set | => | send the clipboard (otherwise send the selection) | |||
| bit 4 set | => | delete the selection after sending the data | |||
| bit 31 set | => | message is for the attention of the Wimp, other tasks must ignore it | |||
| all others are reserved and must be clear | |||||
| R1+24 | destination window handle | ||||
| R1+28 | destination icon handle (-1 if none) | ||||
| R1+32 | destination x co-ordinate | ||||
| R1+36 | destination y co-ordinate | ||||
| R1+40 | pointer to list of data types that the destination task is interested in receiving, in order of preference, terminated by -1 (may be a null list if the native format is required) - now held in the Clipboard's workspace | ||||
| Message_Paste (&4E001) | |||||
| This message informs the task being pasted to or dropped upon that the data is ready to be received. | |||||
| R1+12 | your_ref: 0 | ||||
| R1+20 | flags: | bit 0 set | => | Clipboard couldn't find any clipboard after a Clipboard_Get call - take no further action | |
| bit 31 set | => | message is for the attention of the Wimp, other tasks must ignore it | |||
| all others are reserved and must be clear | |||||
| R1+24 | destination window handle | ||||
| R1+28 | destination icon handle (-1 if none) or internal handle if initiated by a Message_DataRequest | ||||
| R1+32 | destination x co-ordinate | ||||
| R1+36 | destination y co-ordinate | ||||
| R1+40 | data type | ||||
| R1+44 | pointer to data, or 0 if flag bit 0 set | ||||
| R1+48 | data length | ||||
| R1+52 | pointer to proposed leafname of data, null-terminated, or 0 if flag bit 0 set | ||||
Interactions
The five possible interactions during a paste operation are outlined below. The solid lines refer to the complete paste process, and the dotted lines refer to clipboard data type determination, as described in §5.3.2.3. Lines are diagonal where a task switch is performed (i.e. for the sending of messages rather than the use of SWIs). Note that the "clipboard-owning task" is the task that most recently performed a cut or copy operation - strictly speaking, if the task is cooperating with the Clipboard, the Clipboard is the clipboard owner.




Clipboard Data Type Determination
Since the Clipboard is responsible for performing the traditional data transfer protocol, tasks that use the Clipboard need another way in which to determine whether they can use the current clipboard data. This will be provided by the Clipboard using the SWI Clipboard_GetDataType and the message Message_DataTypeIs.| SWI Clipboard_GetDataType (&4E002) | |||||
| Requests data type of the clipboard, using the Clipboard as a proxy. | |||||
| On entry | |||||
| R0 = | flags: | bit 31 set | => | flag reply messages as for the attention of the Wimp (this bit must only be set by the Wimp, even though there are currently no plans for it to do so at present) | |
| all others are reserved and must be clear | |||||
| R1 = | destination window handle | ||||
| R2 = | destination icon handle (-1 if none) | ||||
| R3 = | destination x co-ordinate | ||||
| R4 = | destination y co-ordinate | ||||
| R5 = | pointer to list of data types that the task is interested in receiving, in order of preference, terminated by -1 (may be a null list if the native format is required) | ||||
| On exit | |||||
| R0-R5 preserved | |||||
| The Clipboard takes an internal copy of the data type list. If it owns the clipboard itself, it replies immediately with a Message_DataTypeIs. If a task has registered itself with the Clipboard using a bit-1-set SWI Clipboard_Put, the Clipboard sends a Message_PutRequest to the clipboard owner, and uses the (single) data type returned in the following SWI Clipboard_Put to construct a Message_DataTypeIs. Alternatively, if a conventional drag-and-drop task owns the clipboard, the Clipboard will send a Message_DataRequest, but fail to reply to the subsequent Message_DataSave; the data type from the Message_DataSave is used in the Message_DataTypeIs, thus creating a uniform interface. | |||||
| Message_DataTypeIs (&4E002) | |||||
| This message informs a task of the data type of the clipboard (subject to the data type list passed to the preceding SWI Clipboard_GetDataType). | |||||
| R1+12 | your_ref: 0 | ||||
| R1+20 | flags: | bit 0 set | => | Clipboard couldn't find any clipboard after a Clipboard_GetDataType call | |
| bit 31 set | => | message is for the attention of the Wimp, other tasks must ignore it | |||
| all others are reserved and must be clear | |||||
| R1+24 | destination window handle | ||||
| R1+28 | destination icon handle (-1 if none) | ||||
| R1+32 | destination x co-ordinate | ||||
| R1+36 | destination y co-ordinate | ||||
| R1+40 | data type | ||||
Writable Icons
The Wimp will use the Clipboard to obtain data when it needs to be pasted. It will (effectively) install a temporary post-poll filter on the task owning the icon, in order to detect the flags-bit-31-set Message_Paste that follows a Clipboard_Get SWI call. The message event will not be claimed, so that a task can be kept informed about what is being done to its icons - but the task must not change the contents of the icon, because the Wimp will already have done so. Since the Wimp will only export text from writable icons, and as such will have used the bit-1-clear version of Clipboard_Put, it will not have to respond to Message_PutRequests (except as a result of a drag-and-drop, see §5.4.2). The Wimp will not call Clipboard_GetDataType, so need not respond to Message_DataTypeIs.Drag and Drop
Protocol
During a traditional drag operation, no messaging takes place until the drop. However, during a drag-and-drop drag, a dialogue is set up between the dragging (sending) task and the potentially-receiving (claiming) task - which, in general, is the task owning the window under the pointer at any given time.Responsibilities
The sending task's responsibilities include:- checking the status of the Shift key at the beginning of the drag
- setting the pointer shape to ptr_drop at the beginning of the drag, resetting the pointer shape to ptr_drop when the claiming task has finished with using an alternative pointer shape, and setting it back to ptr_default at the end of the drag
- calling Wimp_DragBox, DragASprite_Start/Stop or DragAnObject_Start/Stop, as appropriate, at the beginning and end (abortion or completion) of the drag, and whenever the claiming task starts or stops requiring that the dragged object be removed from view (during such a period, a type 7 Wimp_DragBox "dragpoint" must be used instead)
- contacting the claiming task every 0.25 seconds, stating the screen position and "real life" bounding box of the data and the data types in which it is available
- initiating the drop when the drag ends
- deleting the selected data after a successful drop if (drag was within the same window AND Shift was not held down) OR (drag was between windows or to a type-15 writable icon in any window AND Shift was held down) OR the destination is a trashcan application
- aborting the drag (and informing the claiming task as such) when the user presses Escape (which means the sending task must retain the input focus throughout the drag)
The claiming task's responsibilities include:
- updating the ghost caret according to the data passed from the sending task, provided at least one available data type can be used (and telling the sending task to remove the dragged object if a ghost caret is being displayed)
- automatically scrolling the window if the pointer is paused near the edge of a document window (and changing the pointer to reflect as such at the beginning of the autoscroll - changing it back at the end is the sending task's responsibility)
- letting the sending task know its preferred ordering of data types, so that the sending task can work out which data type to send during the drop
- letting the sending task know if it the claiming task is a trashcan (i.e. that the source data must be deleted)
A task must only claim the drag if it can do something useful with the handles and co-ordinates passed to it - typically a response would be made when the pointer is over a text area or in the autoscrolling pause zone, but not when over a "dead" area like a page border, and not when over a writable icon (except that being over an autoscrolling pause zone takes precedence over being over a dead zone or icon). In practice, the claiming task can choose to continue to be involved in the dialogue, even when the pointer is no longer over one of its windows. This is to allow autoscrolling to continue, even when the pointer is dragged outside the window being autoscrolled (although this must not occur if the pointer has been moved smoothly over the window boundary without pausing over the window's autoscrolling activation zone). In fact, the default behaviour is for the dialogue to continue between the same two tasks, until the claiming task bows out by letting the sending task's message bounce. The claiming task, being the one handling the autoscrolling, is of course the one that knows best when this is necessary.
Messaging
The sending task sends a Message_Dragging, and the claiming task replies with a Message_DragClaim, as follow:| Message_Dragging (&00011) | |||||
| This message is sent by a sending task to a (prospective) claiming task at intervals of 0.25 second, carrying context-sensitive information about the drag. | |||||
| R1+12 | your_ref: my_ref of last Message_DragClaim (or 0 if there was no claimant last time, or if this is the first Message_Dragging) | ||||
| R1+20 | destination window handle (constructed from Wimp_GetPointerInfo) | ||||
| R1+24 | destination icon handle (constructed from Wimp_GetPointerInfo) | ||||
| R1+28 | destination x co-ordinate (constructed from Wimp_GetPointerInfo) | ||||
| R1+32 | destination y co-ordinate (constructed from Wimp_GetPointerInfo) | ||||
| R1+36 | flags: | bit 1 set | => | sending data from selection (for information only, receiver must ignore) | |
| bit 2 set | => | sending data from clipboard - i.e. from a clipboard-displaying window (for information only, receiver must ignore) | |||
| bit 3 set | => | source data will be deleted (for information only, and unfortunately is incorrect when generated by DataPower; receiver must ignore) | |||
| bit 4 set | => | drag is being aborted, do not respond to this message | |||
| all other bits are reserved and must be clear | |||||
| R1+40 | xmin, ymin, xmax, ymax (4 bytes each): bounding box of data, relative to pointer, measured in millipoints (1/72000th of an inch), not scaled according to the zoom factor(s) of the source window; xmin > xmax means data has no bounding box, or bounding box is unknown | ||||
| R1+56 | list of available data types in no particular order, terminated by -1 (must not be null) | ||||
| Message_DragClaim (&00012) | |||||
| This message is sent by a claiming task to the sending task in response to a Message_Dragging, carrying context-sensitive information about the drag. It must only be issued if the claiming task is interested in at least one available data type. | |||||
| R1+12 | your_ref: my_ref of last Message_Dragging | ||||
| R1+20 | flags: | bit 0 set | => | a pointer shape other than ptr_drop is in use | |
| bit 1 set | => | claiming task requires the absence of the Wimp dragbox / DragASprite sprite / DragAnObject object | |||
| bit 3 set | => | claiming task is a trashcan application, so the source data must be deleted irrespective of Message_Dragging's flags bit 3 (else deletion of the source data is determined by sending task) | |||
| all other bits are reserved and must be clear | |||||
| R1+24 | list of available data types in receiver's order of preference, terminated by -1 (may be null) | ||||
Use
In event-driven terms, the sending and claiming tasks must follow the behaviour outlined below in order to implement every aspect of the protocol. Explanatory comments are italicised (and are all new in this specification). "Message type 17/18" means "use message type 17 unless drag_finished is 'true', when you must use message type 18". This is an optimisation, because we're not interested if Message_Dragging bounces from a non-drag-and-drop task, until the end of the drag, when we will want to send the data by simple data transfer. Sending task:- At drag start,
- enable null events every 0.25 seconds;
- call Wimp_DragBox (with a drag type of 5), DragASprite_Start or DragAnObject_Start as appropriate (remember to use the dragbox if CMOS states that dragged sprites/objects must not be used);
- program pointer shape to ptr_drop;
- set shift_pressed to indicate current status of the Shift keys;
- set claimant to 'none' (-1 is a suitable invalid task handle for this purpose);
- set drag_finished to 'false';
- set drag_aborted to 'false';
- set lastref to 'none' (0 is suitable for this purpose).
- At drag abort (when Escape pressed during a drag),
- disable null events;
- call Wimp_DragBox -1, DragASprite_Stop or DragAnObject_Stop as appropriate (or Wimp_DragBox -1 if old_dragclaim_flags has bit 1 set);
- program pointer shape to ptr_default;
- set drag_finished and drag_aborted to 'true';
- proceed as for a null event...
- At drag end (when User_Drag_Box event is received),
- disable null events;
- if necessary, call DragASprite_Stop or DragAnObject_Stop;
- program pointer shape to ptr_default;
- set drag_finished to 'true';
- proceed as for a null event...
- At null events,
- construct Message_Dragging using data from Wimp_GetPointerInfo and the value of drag_aborted;
- if claimant is 'none', send message type 17/18 to window owner with your_ref = 0;
- else, send message type 18 to claimant with your_ref = lastref.
- When Message_DragClaim is received,
- if drag_finished is 'true',
- drag has ended successfully while a claim is in force
- if drag_aborted is 'false' (this comparison is not strictly necessary, since the claiming task is not supposed to reply when the drag is being aborted),
- initiate enhanced drop operation (send Message_DataSave to claimant, using first possible data type in the list, or the native data type if none are possible, and using your_ref = my_ref of the Message_DragClaim, then delete the source data if shift_pressed and the new window/icon handles (or the trashcan flag bit in Message_DragClaim) indicate as such.
- else,
- drag is continuing AND (a claim is in force, or a claim is starting)
- if lastref != 'none',
- claim is continuing, not just starting
- if old_dragclaim_flags bit 0 is set, but the new Message_DragClaim flags bit 0 is clear, program the pointer shape to ptr_drop;
- if old_dragclaim_flags bit 1 is set, but the new Message_DragClaim flags bit 1 is clear, call Wimp_DragBox (with a drag type of 5), DragASprite_Start or DragAnObject_Start as appropriate.
- if old_dragclaim_flags bit 1 is clear, but the new Message_DragClaim flags bit 1 is set, call DragASprite_Stop or DragAnObject_Stop if necessary, then call Wimp_DragBox with a drag type of 7.
- else,
- claim is just starting
- if Message_DragClaim flags bit 1 is set, call DragASprite_Stop or DragAnObject_Stop if necessary, then call Wimp_DragBox with a drag type of 7.
- set claimant to task handle in Message_DragClaim;
- set lastref to my_ref of Message_DragClaim;
- set old_dragclaim_flags to flags word from Message_DragClaim.
- When Message_Dragging bounces,
- if claimant is not 'none',
- claimant is releasing claim (including when claimant doesn't reply because the drag is aborting)
- if drag_finished is 'false',
- if old_dragclaim_flags bit 0 is set, program the pointer shape to ptr_drop;
- if old_dragclaim_flags bit 1 is set, call Wimp_DragBox (with a drag type of 5), DragASprite_Start or DragAnObject_Start as appropriate.
- set claimant to 'none';
- set lastref to 'none';
- resend Message_Dragging as message type 17/18 to the window owner (preserving the flags, and with your_ref = 0).
- else,
- (no claimant is in effect AND drag has finished) OR the drag is aborting
- if drag_finished is 'true' (this comparison is not strictly necessary, since drag_aborted also implies drag_finished),
- if drag_aborted is 'false',
- initiate simple drop operation (send Message_DataSave to window owner, using native data type and your_ref = 0).
- At initialisation,
- set claiming to 'false'.
- When Message_Dragging is received,
- if claiming is 'false',
- if flags bit 4 is clear,
- start claim
- set claiming to 'true' and autoscrolling to 'false';
- if pointer is in the autoscroll pause zone,
- set pausing to 'true';
- set old_pointer_x, old_pointer_y and old_pointer_time to the x and y from Message_Dragging and the current monotonic time;
- program pointer to autoscroll-pause shape, and set pointer_altered to 'true';
- else,
- set pausing to 'false' and pointer_altered to 'false';
- if the data type is suitable, draw the ghost caret (I-beam or bounding box) and set ghost_caret to 'true', else set ghost_caret to 'false';
- reply with Message_DragClaim (message type 17), using pointer_altered and ghost_caret to determine the flags.
- else,
- if flags bit 4 is clear AND (claiming task owns the window/icon handle in Message_Dragging OR autoscrolling is 'true'),
- update claim
- if pausing is 'true',
- if current pointer x or y differs from old_pointer_x or old_pointer_y, set old_pointer_x, old_pointer_y and old_pointer_time to the current pointer x and y and monotonic time;
- if pointer has left autoscroll pausing zone,
- set pausing and pointer_altered to 'false';
- else,
- if (current monotonic time - old_pointer_time) >= pause_time (typically 0.5 seconds), set autoscrolling to 'true' and pausing to 'false', and program the pointer to its autoscroll-active shape;
- else if autoscrolling is 'false',
- if pointer is in the autoscroll pause zone,
- set pausing to 'true';
- set old_pointer_x, old_pointer_y and old_pointer_time to the x and y from Message_Dragging and the current monotonic time;
- program pointer to autoscroll-pause shape, and set pointer_altered to 'true';
- else,
- set pausing to 'false' and pointer_altered to 'false';
- else (i.e. autoscrolling is 'true'),
- if pointer is over the window, but not in the autoscroll pause zone,
- set autoscrolling and pointer_altered to 'false';
- else,
- scroll the window by an amount proportional to the distance from the pointer to the inside edge of the autoscroll pause zone;
- if the window cannot be scrolled any further in this direction (or can be scrolled in neither direction if a 2D scroll), set autoscrolling to 'false', set pausing to 'true' and program the pointer to its autoscroll-pausing shape;
- if ghost_caret is 'true', update ghost caret - unless the work-area-relative position is unchanged, undraw the old ghost caret and draw the new ghost caret;
- reply with Message_DragClaim (message type 17), using pointer_altered and ghost_caret to determine the flags.
- else,
- release claim
- set claiming to 'false';
- if ghost_caret is 'true', undraw the old ghost caret;
- let Message_Dragging bounce (i.e. don't reply to it).
- When Message_DataSave is received,
- if you_ref != 0,
- if claiming is 'true',
- this was an enhanced (full drag-and-drop) drop - the claim was never released
- set claiming to 'false';
- if ghost_caret is 'true', undraw the old ghost caret;
- import data to the last ghost caret position using conventional data transfer protocol (preferably using memory data transfer).
- else,
- this is part of the paste protocol
- continue as for simple drop...
- else,
- this was a simple drop
- import data to position from Message_DataSave using conventional data transfer protocol (preferably using memory data transfer).
Clipboard Module
Use
The Clipboard module, in conjunction with the SWI Wimp_AutoScroll, will reduce the coding required to implement drag-and-drop to the following, a great improvement on §5.4.1.3. Note that, unlike the clipboard maintenance and paste protocols, the drag and drop protocols use one-to-one messages rather than broadcast messages, so the Clipboard needs to make use of filters in order to translate between the protocols. (An assumption has been made that the receiving task wishes to use an I-beam ghost caret - this does not have to be the case, but Wimp_SetCaretPosition's new facility for drawing ghost carets requires simpler but different code from that in §5.4.1.3.) Sending task:- At drag start,
- ensure sending window has the input focus;
- call SWI Clipboard_StartDrag.
- When Message_PutRequest is received,
- if flags bits 3 and 31 are clear,
- this is a PutRequest for the selection, rather than the task-managed clipboard
- translate selected data to the first possible data type in the list, or leave as the native data type if none are possible;
- call Clipboard_Put to send the data;
- if flags bit 4 of the Message_PutRequest was set, delete the selection.
- At initialisation,
- set claiming to 'false'.
- When Message_Dragging is received,
- if claiming is 'false',
- if flags bit 4 is clear,
- start claim
- set claiming to 'true';
- call Wimp_AutoScroll;
- call Wimp_SetCaretPosition to position the ghost caret if at least one available data type is suitable;
- reply with Message_DragClaim (message type 17), with flags bit 0 clear, and flags bit 1 set if a ghost caret is being displayed.
- else,
- if flags bit 4 is clear AND (claiming task owns the window handle in Message_Dragging OR Wimp_AutoScroll indicates scrolling is in progress),
- update claim
- call Wimp_SetCaretPosition to reposition the ghost caret if at least one available data type is suitable;
- reply with Message_DragClaim (message type 17), with flags bit 0 clear, and flags bit 1 set if a ghost caret is being displayed.
- else,
- release claim
- set claiming to 'false';
- call Wimp_AutoScroll to deactivate autoscrolling;
- call Wimp_SetCaretPosition -1 to remove the ghost caret;
- let Message_Dragging bounce (i.e. don't reply to it).
- When Message_DataSave is received,
- if claiming is 'true',
- this was an enhanced (full drag-and-drop) drop - the claim was never released
- set claiming to 'false';
- call Wimp_AutoScroll to deactivate autoscrolling;
- call Wimp_SetCaretPosition -1 to remove the ghost caret;
- copy window handle, icon handle, x and y offsets from last Message_Dragging over the Message_DataSave block equivalents, and call Clipboard_CatchDrop.
- else,
- this was a simple drop
- call Clipboard_CatchDrop.
Messaging
The details of the new SWIs introduced are:| SWI Clipboard_StartDrag (&4E003) | |||||
| Starts a drag-and-drop drag, using the Clipboard as a proxy. | |||||
| On entry | |||||
| R0 = | flags: | bit 1 | => | as Message_Dragging (= sending from selection) | |
| bit 2 | => | as Message_Dragging (= sending from clipboard) | |||
| bits 14, 15 | 0 | => use rotating-dash fixed-size Wimp dragbox | |||
| 1 | => use DragASprite | ||||
| 2 | => use DragAnObject | ||||
| 3 | => reserved | ||||
| bit 16 | => | as DragAnObject_Start, if applicable (R1 is a pointer to a routine rather than a SWI number) | |||
| bit 17 | => | as DragAnObject_Start, if applicable (if bit 16 is set and bit 18 clear, enter routine with R10 below R13 - note this was previously misdocumented as the routine being entered in SVC mode rather than USR mode) | |||
| bit 18 | => | as DragAnObject_Start, if applicable (if bit 16 is set and DragAnObject is version 0.09 or later, enter routine in USR mode rather than SVC mode) | |||
| bit 31 set | => | flag reply messages as for the attention of the Wimp (this bit must only be set by the Wimp) | |||
| all others are reserved and must be clear | |||||
| R1 = | sprite area or renderer (if DragASprite or DragAnObject, respectively) | ||||
| R2 = | pointer to sprite name or register/parameter block (if DragASprite or DragAnObject, respectively) | ||||
| R3 = | source window handle (used in combination with the Shift key state to determine when the source data needs deleting afterwards) | ||||
| R4 = | pointer to word-aligned block containing three bounding boxes, each made up of four 32-bit quantities held in the order xmin, ymin, xmax, ymax, where the minima are inclusive and the maxima are exclusive:
| ||||
| R5 = | data length, bytes | ||||
| R6 = | pointer to non-null list of data types that the task can translate the data to (in no particular order), terminated by -1 | ||||
| R7 = | pointer to proposed leafname of data, null-terminated | ||||
| On exit | |||||
| R0-R7 preserved | |||||
| The Clipboard takes a copy of the data pointed to, and performs the actions described in §5.4.1.3 (sending) on behalf of the task. In order to achieve this, it forces the required Wimp events to be unmasked using a pre-poll filter, then performs its main actions using a post-poll filter; it also calls Wimp_AddMessages, so it not necessary for the task to register interest in Message_DragClaim etc. at initialisation. During the drag, the task will not see any user_drag_box events, key_pressed events (except for Escape), or any DragClaim, RAMFetch, DataSaveAck or DataLoadAck messages. If null events were enabled in the poll mask before it was massaged by the pre-poll filter (and, if it was a call to Wimp_PollIdle, the required time has passed) they will also pass through to the task once the post-poll filter has done its work. | |||||
| When the drag ends (successfully or not), the filters are removed. When the drag ends successfully, the task's cooperation is required in order to translate the data to the required data type; this is accomplished by the Clipboard sending it a Message_PutRequest with flags bit 3 clear, as described in §5.3.2.1. | |||||
| SWI Clipboard_CatchDrop (&4E004) | |||||
| Request the Clipboard to act as a proxy for data transfer during a drop. | |||||
| On entry | |||||
| R0 = | flags: | bit 31 set | => | flag reply messages as for the attention of the Wimp (this bit must only be set by the Wimp) | |
| all others are reserved and must be clear | |||||
| R1 = | pointer to DataSave message block (or DataLoad message block if initiated by the Filer) that needs replying to | ||||
| On exit | |||||
| R0-R1 preserved | |||||
| The Clipboard handles the data transfer for the task, trying memory data transfer first if possible. When the transfer is complete, the Clipboard sends a Message_Paste to the task that called this SWI, so as to appear identical to a paste operation. | |||||
| It will also detect if it sent the DataSave message itself - in other words, if the sending task was using the Clipboard as a proxy too - if so, no further messaging will occur, and the Clipboard will simply use the pointer to its copy of the data made during Clipboard_Put in the Message_Paste. | |||||
Writable Icons
The Wimp will handle drags to and from writable icons as in §5.4.2. The Wimp will install an internal message filter in order to listen for Clipboard messages (Message_PutRequest and Message_Paste) with flags bit 31 set; these are handled by the Wimp and not passed on to the task. Similarly, it will intercept and not pass on Message_Dragging throughout any period when it is claiming the drag. However, some tasks (such as FrontEnd) do perform useful functions when they receive a Message_DataSave, so Message_DataSave is always passed through to the task, and the Wimp will only call Clipboard_CatchDrop at the Wimp_Poll following the delivery of Message_DataSave if the task didn't call Wimp_SendMessage, Wimp_UpdateWindow or Wimp_ForceRedraw.Data Formats
No new data formats are introduced.Dependencies
The new Wimp provides facilities not available in earlier versions. Although the source release means that it is possible for applications that use them to require users of older Wimps to upgrade them, the authors may choose to implement them manually in cases where an older Wimp is detected. However, it is encouraged that the new Wimp facilities be utilised when possible, to accommodate future GUI changes, to allow system-wide configuration of autoscroll behaviour and so on. The Wimp will require the Clipboard to enable functioning of drag-and-drop to or from writable icons. Without it, selections will be able to be made, but no operations (other than deletion) can be performed on them, and no selections from other applications will be inserted when dropped on a writable icon.Acceptance Test
Clipboard Module
Compatibility
The most advanced features of RISC OS that the Clipboard will make use of are Dynamic Areas and the DragAnObject module, both introduced at RISC OS 3.50. Provision may be made for further development work to be done to support versions back to RISC OS 3.10 (by using RMA rather than Dynamic Areas, and defaulting to rotating-dash boxes when a DragAnObject drag is requested), but for the purposes of the initial release, a modern OS may be assumed.Reliability/Robustness
The module must be able to handle at least a thousand consecutive operations without crashing. Null-length data, extremely long data and data close in length to a multiple of the page size must not cause problems. Bad parameters (e.g. illegal sprite area pointers) must be handled as well as possible - in the example, a rotating-dash box must be used instead.Performance
Performance will unfortunately continue to be slow in certain key situations - for example, when transferring data to a conventional task by memory data transfer, where the receiving task has specified too small a buffer. Memory transfer will be slower during drops, since the data is copied twice, once to the Clipboard's application slot, and once from it. The incidences of scrapfile transfer will however be reduced, resulting in speed gains.Memory Usage
The module itself must not exceed 32kB in length. Stored global clipboard data and transient data (during a drop operation) are stored in the Clipboard's application slot so that the only size limits are those of the application slot size (not a big issue with modern memory maps) and the amount of physical RAM available. The application slot shall grow and shrink so that it is no larger than the combined size of the data stored, rounded up to the next page boundary. The RMA shall be used for general heap storage (linked lists etc.).Wimp Writable Icon Code
Compatibility
The writable icon code will function correctly for all tasks that follow the revised guidelines in §5 and all tasks that do not support the drag-and-drop protocol, but it may lack complete functionality (although not to the extent of rendering it useless) for up to 10% of the writable icons in existing applications written to the old application note guidelines.Reliability/Robustness
The writable icon cut-and-paste / drag-and-drop code must be at least as reliable as the Clipboard module.Performance
Redraw of writable icons, especially when delimiting a selection with autoscrolling active, must not cause flicker. Data transfer operations must not be appreciably slower than the Clipboard routines that are actually doing the work.Memory Usage
Writable icon data is usually held in application workspace, and will not increase in size by virtue of these enhancements. A negligible amount of extra module workspace will be required to hold the details of the Wimp selection and ghost caret, this should typically be no more than 32K.Non Compliances
No attempt will be made to develop an selection-drawing algorithm that can cope with overlapping icons. The appearance of such icons after scrolling and redrawing is not defined.Development Test Strategy
Test applications will be written to exercise the Clipboard SWIs. Drags to and from the existing drag-and-drop applications (e.g. DataPower, EasiWriter and TechWriter) work seamlessly. These applications will therefore be important testing tools. Also for testing purposes, a drag-and-drop trashcan application and simple clipboard-display application will be written. (Conventional data transfer (as for example, when dropping a selection on to a Filer window) is not expected to cause significant problems, as the protocol has been clearly defined for a long time, unlike the protocol in the application notes.) A test suite will be written to exercise the functions of the Clipboard through exercise of writable icons' cut-and-paste / drag-and-drop facilities. For example: setting of writable icon selections will be tested repeatedly, involving operations that change one or both ends of a selection (or neither) at the same time, both with and without the presence of a ghost caret. This will be done by direct calling of Wimp_SetCaretPosition. And text files of differing length, of differing line terminator and files that have been accidentally mistyped as text will be saved on to writable icons of differing validation strings, using conventional data transfer, pasting and dropping.Product Organisation
This document, and the code it describes, form part of the Shared Source RISC OS release. The user interface issues should ideally be included in a new version of the Style Guide, and the APIs and messages in a new version of the Programmer's Reference Manual. Use of the raw protocol rather than the Clipboard module will be deprecated. The Clipboard module can be softloaded, but must also be capable of being built into ROM.Future Enhancements
None planned.Glossary
| AND conj. | Logical AND. |
| Caret n. | The position in a document where typed characters or pasted clipboard contents will be placed. Many pre-drag-and-drop applications also use this position as the insertion point for dropped data, but drag-and-drop applications must use the ghost caret for this purpose instead. In textual documents, the caret is often shown by a red I-beam, but other representations of the caret may be more appropriate for other kinds of data. Some editors, such as !Draw, do not have a visible insertion point, but still "grab the caret" and mark it as invisible, in order to gain the input focus so that they may receive keystroke events. |
| Clear v. | The operation by which a selection is undone. |
| Clipboard n. | A hidden, temporary storage area that holds any type of data while the user is copying or moving it using the cut-and-paste protocol, whether internal to one application, or between applications. Conceptually, there is only one clipboard, but the actual storage area may actually be managed by different applications or modules, depending upon the circumstances. |
| The term may also be used to refer to the Clipboard module, although in this eventuality, the initial letter will be in upper case. | |
| Copy v. | The operation by which the current selection is replicated in the clipboard, overwriting any existing data in the clipboard. |
| Cut v. | As copy, but the selection is subsequently deleted from its original location. |
| Data type n. | A value equivalent to a filetype, but not necessarily referring to a file. |
| Drag v. | The operation by which the user indicates where they wish a selection to be copied or moved to by dragging a representation of the data from the selection to the destination. |
| Drop v. | At the end of a drag, the actual data transfer process. This combines the functionality of a paste operation with either a cut or copy operation, as appropriate. |
| Ghost caret n. | During a drag operation, the position in a document where the data would be inserted, were the user to release the mouse button. In textual documents, the ghost caret is often shown similarly to a normal caret, but coloured grey, and "snapped" to the nearest character boundary. Other documents might better display the ghost caret as the bounding box of the data, scaled according to the destination window's zoom factor(s). |
| OR conj. | Logical inclusive OR (i.e. not EOR) - used where the 'or' would have an ambiguous meaning, for example in English text. |
| Input focus n. | The defining attribute of the window where keystroke events will be delivered. The user may be able to see a caret or a selection, or possibly neither, in the window that has the input focus; the window border will be coloured in an alternative colour (conventionally cream). Any parent nested windows (recursively), and any non-pane window behind a pane window, will also have their title bars recoloured. |
| Paste v. | The operation that the user performs to copy the clipboard contents into a document, at the caret. |
| Selection n. | The portion of a document which the user has chosen as the target for subsequent operations. This may be a contiguous selection (as in the case of selected text) or a non-contiguous selection (as in the case of a number of selected files in the Filer). The rendering of the selection is media-dependent, but typically may be shown by inversion of the colours of the selected region, or alternatively by the drawing of a bounding box around the selection(s). |
| A shaded selection, which ought be rendered to match the Wimp's rendering of shaded selections in writable icons, indicates the location of a selection after another selection has been made in another window - but not when a caret or selection is made in a non-drag-and-drop application. | |
| Shadow caret n. | The equivalent of a shaded selection, but for carets. A shadow caret must not be rendered in such a way that it can be mistaken for a ghost caret. It is optional, because applications are expected normally to use a Wimp-drawn caret, and the Wimp does not support shadow carets. However, shadow carets can be useful, especially if the application draws its own caret anyway (as, for example, if an I-beam is an unsuitable), because they fix an insertion point for a drop, whenever one or both of the sending and receiving tasks uses pre-drag-and-drop data transfer protocol. The shadow caret is also the position to which the caret will be returned if the user Adjust-clicks on the window, or clicks in a "dead" region of the window, such as a page border; this is particularly useful in cases where repositioning the caret would be time-consuming or fiddly, for example if the caret is in a deep "layer" of a document. |
References
[1]: Support Group Application Note 240: The RISC OS Selection Model and Clipboard [2]: Support Group Application Note 241: The RISC OS Drag-and-Drop System [3]: RISC OS 3 PRM 3 §53: The Window Manager, pp 3-249 - 3-256 [4]: RISC OS 3 Style Guide §11: Handling selection, pp 75-78 [5]: Document Ref 1309,413/FS: Ursula Window Manager Changes Functional SpecificationHistory
| Revision | Who | Date | Comment |
| A (aka 0.00) | BJGA | 12-09-1997 | Started |
| B (aka 0.01) | BJGA | 13-10-1997 | First release for comment |
| C (aka 0.02) | BJGA | 14-10-1997 | Released for review |
| D | BJGA | 19-05-1998 | Prepared for D.O. |
| E | BJGA | 26-02-1999 | Started reworking document for Java 1.2 project, didn't get far before cancelled again |
| F | BJGA | 16-10-2007 | Finally finished integrating the Ursula review comments and 8 years' worth of mental notes, for initial release alongside shared source code |