Core Applications

The core three applications, !Paint, !Draw and !Edit had been quite static up until Select 4. Although they had all received additions in the form of the clipboard support, they had not been updated significantly. !Edit was still a very poor text editor by any standards, even allowing for the fact that it was had most basic of functions.

!Paint had been given a good number of updates in the final two releases, as ImageFileConvert support was added, and Ian Jeffray gave the entire application a little bit of a face lift as well as significantly reworked the innards. !Draw had gained support for importing through the ImageFileConvert system, saving to SVG and clipboard support, but was otherwise pretty much unchanged.

John Ballance had on one occasion stated that the only thing he felt was worth keeping out of Select was the clipboard support, which seemed to set a lot of the tone for how little value he saw in the work I had done, alas. The clipboard support was relatively trivial within the applications.

As I had done with !ResEd, I wanted to introduce external edit protocol support to the applications. This might not seem significant, but I really liked the protocol and felt that it was a good way to allow users to select their applications and integrate them with one another. One drawback with the external edit protocol was that it did not provide any mechanism for in place editing.

Protocols such as the Clares' Plug In Compliant Application ('PCA') protocol did allow for in place editing, but it also focused on low memory usage, which was nice, but it significantly complicated the implementation. Their protocol also did not fit into a more commonly used client/server design, and had quite badly named messages. Though it might allow more, it had never appealed to me.

At the very least, providing support for external edit of text files, DrawFiles and Sprite files would encourage greater client usage - instead of building in an editor, clients could launch the external editor to do the job. !Zap and !StrongEd already supported the protocol for text files.

!Paint had already been updated to be able to plot text in fonts, which made the application more attractive for quick doodles. !Draw was still far better at drawing many things, but it wasn't very clear how you could create a sprite of your masterpiece. It is actually quite simple - drop the diagram on to !Paint, and a sprite will be created through the ImageFileConvert protocol - but it might be clearer to offer the save option on the menu.

It would be useful if !Paint offered an 'undo' option. This would require more memory, but would be a lot more flexible and less frustrating when you accidentally clicked in the wrong place.

!Draw offered options for isometric and rectangular grid alignment, and you could align groups, but there was no option for guides. Guides, and similar marks, might make it easier to lay out some technical diagrams. It would be nice, although possibly costly in processor time, to offer full feedback on the shapes being edited, rather than just showing the skeleton lines. On the other hand, !ArtWorks provided that facility, and it did not suffer significantly. Drawing diagrams with arrow heads of dashed marks could be frustrating as you needed to release the drag in order to see the thick lines, arrows and dash marks.

The !Draw toolbar should have been given the option to be placed at the top or bottom of the window, rather than hanging down the left side. This might allow the tools to be better positioned for some users. Offering the directly accessible option to undo and redo on the toolbar might also be a usability improvement (akin to the browser back and forward, if that design was being used).

Providing a named colour set could be advantageous within !Draw. Although the objects in a DrawFile do not allow for any colour specification other than RGB, it would be useful to be able to select RGB colours by name, and store them within the file format (so that they could be reloaded with the document) or controlled independently.

I had long wanted to update the ColourPicker module to allow another selection model - that of named colours (which could be supplied in one of the other model formats). This would provide a number of standard colours, which could be configured by the user, and which the application could also supply for the dialogue.

The application supplied colour set would allow custom named document colours (as above) to be exposed in the interface. This would clearly need to be either additive or to replace the default colour set. As the default configured colour set would be shared, colours configured in one application could be used in another.

In addition to the default set, other colour sets might be selectable, such as simple sets like 'primaries and secondaries' and 'web safe', or more complex ones like 'Pantone®' (obviously requiring ludicrous money to license!).

Allowing colour replacement within the selection in !Draw would be useful, although obviously it begins to step on the toes of !Chameleon. It is hard not to add features without finding that they encroach on some of the ground covered by other applications, and this was one reason why the applications were not enhanced significantly. Adding named groups might make it easier to find the right shape when controlling a large scene, as might adding the ability to place objects within layers.

It had been requested in the past that there be a programmatic interface to !Draw so that the objects in the diagram could be manipulated by other applications. I think that some of this came from application authors that just wanted to leverage the abilities of !Draw, which they could not achieve themselves to make a composite application. But that isn't a bad thing in itself - providing control over applications is actually very useful, and should have been wider.

Automation

I remember that soon after RISC OS 4 shipped, whilst we were investigating little things, we looked at adding a command message protocol to one of the core applications. I don't have any record of what we did, or how we were planning on achieving it. David Thomas suggests that we might have started a TechNote on it, but never finished.

There is a simple control language inside !Edit that was never finished. It looked interesting for a little bit, but I do not think it was particularly reusable as part of a system to control applications. An attempt at a generalised application control protocol was used by Acorn in !Browse and !WebServe, but it was still highly specific to the problem domain.

The method of controlling an application can sit alongside that of the external edit or other similar protocols. There are a few fundamental parts to controlling the application. There needs to be a way to establish that an application can be controlled, and what facilities it offers. There needs to be a way to determine what documents can be operated on (although this could be considered a part of the discovery process, and obviously there need to be manipulation operations such as load which do not have a document on which to operate). Within documents there may be operations which can be performed directly (for example, Save), or which need a selection (for example, Copy, or change colour), or which create new documents (for example a 'new view'), and those which select sub-documents (for example selecting a sprite within a sprite file).

There are many ways these operations could be cut, but probably using a simple verb vocabulary, with a context and modifiers, would be flexible enough to allow applications to export most of the core functions. Essentially anything done from buttons, keyboard or menus should be triggerable through the interface. Additionally, it should be possible to request information as well, although this would be complicated by the large variation of each application's domain. It is likely that common properties would need to be defined in order to allow applications to be controlled independently.

I had an idea that the Toolbox gadgets might also export verbs for their buttons and messages. In addition to identifying the operations it might make automation simpler. The context would always need to be determined, but the verb operation trigger might be simplified if the operations were interpreted by the Toolbox, and just converted to the relevant Toolbox messages. The application could be oblivious to how it was being driven.

The property retrieval would allow simple scripting to control an application and automate some operations that might otherwise be monotonous. With a bit of thought, applications might even be able to respond to requests to record their operations by outputting the verbs and contexts, as they were performed. Of course, this adds a lot of extra work to the application, which is why it would be nice if the Toolbox could take some of the work out of the author's hands.

Some verbs, like 'LOAD' and 'CLOSE' would be supported by most applications, but more specialised operations like 'EMBED' to place a window inside another one might not be supported by some - those that did support it could be made to look more like integrated applications.

Applications structured to accept their input in the form of such operations would also be better placed to have their interface changed by the author, as the operations could be triggered in many different ways. So, in that respect, supporting such a system would make for better designed applications. I am not at all convinced that this in itself would be an easy sell to developers, though.

Iconbar abstraction

The IconBar, as the place where running applications provide their primary control interface, had been unchanged in functionality since RISC OS 2. It might be argued that it hadn't really changed since Arthur. The presentation has changed slightly, with a 3D effect having been added in RISC OS 4, but the difference is not significant. The fixed use of 48 pixels at the bottom of the screen for the IconBar was wasteful for some use cases. This was especially true for wide screen devices, which were generally reducing the vertical resolution, rather than increasing the horizontal resolution.

The IconBar itself could not be varied in position; it was at the bottom of the screen, and that was the end of the story. I had added some support to Pinboard to allow it to take advantage of more space if it was available, but generally the applications assumed (in the limited cases that they needed to) that it was at the bottom of the screen.

There had been changes to the use of the IconBar over the years, mostly to tighten up the rules on where applications should appear. David Thomas (I believe) produced the definitive description of where applications should place their icons on the IconBar for consistency. The side of the IconBar and the priority were constrained so that applications and utilities appeared consistently.

I wanted to replace the IconBar entirely. Rather than being a real window which had real icons on it, it could be... well, anything you wanted. A drop down menu bar, a full screen selector, a pop up bar that contained both running and inactive applications (Mac OS X, I'm looking at you), or whatever. The WindowManager could manage the lists of icons, but the presentation could be handled independently.

I had put together tests (as mentioned in the Desktop ramble), where multiple applications could be running and could 'claim' different parts of the icon bar. The side and priority of the IconBar having been clearly defined meant that if you wanted all the discs to be grouped into one presentation, you could filter them off very simply. Together with the ability to render icons larger than they would usually be, through the Vector icons, this would allow higher resolution, or even warped icons on the IconBar. Together with the colour mapping, icons could change colour according to their state.

All these are features that were harder to handle with the implementation of the IconBar being restricted to the Wimp. Although my prototype used WimpSWIve to handle the replacement interface, my intention was that new filter types could be created and an IconbarManager would perform the actual job of filtering the presentation to other clients. By default the IconbarManager would just present the normal IconBar, but might also have the ability to place the regular IconBar at the sides of the screen.

There were a lot of different ways that the applications could be presented, and the only part of the application which was specific to the application was the opening position of the menus. When you click Menu on the IconBar, the bottom line of the menu is meant to be just above the icon, so is at a fixed location. This means that the application does a calculation for number of lines in the menu and the height of those lines, and positions the menu top relative to the known position of the IconBar icon.

If the IconBar was in a different position, the menus that appeared would not have that restriction. There are two main ways that this could be handled. The WindowManager could trap the menu creation following an 'IconBar' Menu click and force the menu to appear at a different location. This would be a special case, but could be tied to the filtering of the IconBar icon creation operations, if it was done carefully. The disadvantage to doing this would be that it was a special case, and the WindowManager would need to know that it was being treated as an IconBar click (internal filtering on the window handle would probably suffice). A precedent had already been set for this sort of override; the width of menus was originally determined by a size property, specified in the window block, but when proportional fonts were introduced to the desktop the size wasn't as easy for the applications to calculate, so the WindowManager would calculate the size itself.

Another way it could be handled would be for the IconbarManager to use the Wimp SWI filters (the ones that the WindowManager itself provided) to override the position of menu creation. This would leave all the special case handling in the IconbarManager, but would require the use of the SWI filters, which wasn't as tidy.

Either way, the menu creation would end up filtered in the IconbarManager, and a suitable override position could be set by the applications when they registered the filter. It is also possible that an application might display windows in response to clicks in the IconBar icon, so it there might need to be similar filtering on those operations.

The abstraction of the IconBar would also make it easier to handle the cases where the IconBar was intended to live on a single screen of a dual head display. The IconBarManager could suggest the primary dimensions and position of the display to the handling applications on a mode change (and on registration). The applications could easily override that, but it would allow for a consistent (and configurable) setting for the display.

TaskManager

Changing TaskManager had been discussed many times, and prototypes had been produced, and ideas thrown around for ways to change it. The problem with any change to the TaskManager is that it ends up needing quite significant work, because the entire module is in assembler, and the layout is quite tightly coupled the code. The application is optimised so that it does not redraw too much, and is still representative of the system.

I had confused things slightly be allowing the dynamic areas display to be able to include hardware mapped regions (in blue). They meant that the totals of the bars would not add up to the amount of memory available in the machine - not that that had been the case previously anyhow, because of some of the areas which had no presentation.

However, as the dynamic areas had been brought into existence to help with Select's memory management, it should have been possible to present a more accurate view on the use of memory within the system. The more important question was whether this was useful.

One of the reason that there had been different ideas for TaskManager was that it looked pretty simple, and hadn't been updated over the years. The main reason that few of the ideas had stuck had been that it worked very well at what it did.

I had considered moving the dynamic areas from the end of the list, closer to the applications list, as those were the two major users of memory. The downside to this is that dynamic areas are added and deleted more often than applications, and their changes would mean greater redraw for the following sections (system areas).

The question also has to be asked as to why the system areas are treated differently at all. After all, the Relocatable Module Area is just a dynamic area like any other, and so on for all the other system areas.

Some of the designs we had done whilst at RISCOS Ltd had included separating the dynamic areas into their own window, and allowing the applications to have more operations. Independently, Jonathan Brady had written a very nice little filter on the TaskManager menus that let the tasks offer menu items alongside the 'Quit' options. This does break the idea that the TaskManager is for controlling the tasks at a high level, but was quite neat.

TaskManager provides 4 major functions - listing and quitting tasks, displaying acknowledgements information, managing the shutdown of tasks, and breaking down memory use. The memory breakdown was partly tied to the way that tasks were listed, as it was possible to change the size allocated to some tasks.

The shutdown sequence was pretty self contained and could easily be split off into another task if necessary. Similarly, the acknowledgements information was not difficult and could be handled separately. Is it really the job of the TaskManager to deal with these things? Possibly, but it is also a bad design to have this one task do many jobs - especially when those jobs are not necessarily best handled by it. The shutdown sequence, for example, is handled by the TaskManager because it keeps a list of the tasks that are running, which it does in order to present the list to the user in a window.

Surely the list of running tasks should be obtained from the WindowManager, not from an application running under the WindowManager? Especially as the TaskManager can be confused by tasks sending false messages - they could send a broadcast notification that they had been quit, and the TaskManager would act on it. That is one message that I wanted to prevent tasks from being able to send - they should not be able to hide their existence from the user.

Because the TaskManager collects its information about the tasks that are running by watching for their start up messages, it has to start as one of the first tasks to run. If it does not, for example because you loaded a new version, then it will only know about the tasks that started after ran in the desktop. Really it should obtain the details about the running tasks from the WindowManager.

Additionally, this would allow the TaskManager to be reliably replaced, or at the very least to remove its desktop presence in order that another presentation be used for the tasks.

There was one other area that the TaskManager provided, which had been obsoleted with no replacement. That is the desktop save protocol. The problem with the desktop save protocol is that it wasn't designed with other start up scripts in mind.

For example, if you configured !Paint to run during the start up sequence through the configuration tool, and then saved the desktop file through the old desktop save protocol, !Paint would add itself to the applications to start. The result would be that there would be two applications loaded, one from the configuration and one from the saved file.

Additionally, the applications that were saved would not, by default, know what state they needed to load. Filer would write multiple commands that would open the necessary views on to directories, in the correct locations on the screen, but this required that there be a command that could perform these operations. How would you make a text editor load a few documents and place the cursor at the current location in them? You couldn't easily do this.

I wanted to define a slightly different protocol - it couldn't reasonably reuse the old protocol without some thought (maybe you could have a helper tool which was the command that was invoked to perform the operations, but it would need some serious thought). Essentially the applications should be able to supply a command which would run them, and the system would create a start up script which ensured that the necessary applications were loaded - if an application had already been started, it would use the one that had already started.

Together with the command to start the application, each application could write a file which contained the necessary status information necessary to restore its state. This state file would be supplied to the application which had been started (through a message), and it could then restore the necessary state. In Filer's case it could just write the necessary *Filer_OpenDir commands, and when told to load the state it would merely execute the contents.

Other applications could store other information, such as their positions, and maybe even undo information, if necessary - it is also possible that the state might contain the actual file content, if the application felt that was suitable.

Because the applications that were started, and their state, would be more tightly controlled, this would mean that the configuration application could be modified to understand the state - for example, it could be made clear that there was associated state with each of the application state. It is likely that they wouldn't be able to edit the saved state, but maybe that could be a future refinement.

I had planned to add the protocol during the post-RISC OS 4.0 releases. The option to save the desktop had been removed during RISC OS 4.0 development, because I viewed it as bad idea to encourage people to use the old save protocol which could not work as expected.

There was another way that I could have gone at the time. I could have made the saved desktop file overwrite the contents of the applications that were run on start up, effectively replacing the output of the configuration application. As the configuration application could not be guaranteed to be able to interpret all types of application run commands and any other configurations that might be added, I felt that this was a poor solution. You would have been nearly guaranteed that going to the configuration tool after saving the desktop state would omit some of the information that it could not parse.

The protocol I wanted to create also had the benefit that it would allow applications to say 'save state' and be able to be restored back to where they were. This was, of course, assuming that anyone actually took on the new protocol - which was one of the reasons that I had not pursued it. Even protocols that people expected to be working, like the Clipboard had a very poor track record of support from applications, so expecting another protocol to be supported was unlikely to gain much ground. But that isn't to say I didn't want to do it - it would round out the integration quite nicely.

Tool tips protocol

One of the areas that I felt that the Toolbox, and other areas, might benefit from was in providing a 'Tool tips' feedback. RISC OS has, from its early days, provided a help protocol which allows applications to provide information to users about the actions of a button or a region. These have been supported to various degrees by third parties - and I tried to ensure that suitable messages were included in the programs that I supplied. Toolbox supported the help protocol, and handled all the queries itself without any support from the application (unless it wanted to, of course).

The help protocol was mostly intended for descriptive messages about the actions that could be performed. For example, explaining the actions that would be performed if the button was clicked with Select or Adjust, or objects dropped on it. These descriptions were very useful if you needed to work with a new application that you had never used before and wanted to see all the operations available.

These sorts of descriptions are often too heavyweight for some cases. In many cases you just want to know what the button or region does, rather than how to use it. Where there are a lot of different types of operations that can be performed it is often useful to supply a wordy description, but many buttons or regions only have a single use, or a use which is sufficiently obvious that there is no need for longer descriptions.

This is where tool tips have fitted in to other systems. There are few systems that have this sort of medium length descriptions that the Help protocol provides. That isn't a criticism, merely a comparison. These descriptions are often useful, and fill the place where many applications provided 'Hints' boxes when the application started.

A tool tips protocol would provide an internationalised description - usually just a single verb - for the regions, and would appear after a short period hovering over it. The protocol would be similar in many respects to that of the help protocol, and would probably be suitable to insert into the &5## message block which the help protocol lived in. Like the help protocol, a separate application could provide the support for it, but would be resident without a visible desktop presence (that is, no icon bar). This might mean that it needed to be controlled through messages, but this would be a requirement in any case, as third-party applications should be able to replace it.

Toolbox could easily provide the basic support, although it would mean a change to the definition of some Toolbox objects in order to support the new definitions. A few people contributed some ideas to how we might get a useful implementation to work without impacting the applications much. Suggestions such as including the message text in the icon indirection strings to free the application from directly supporting the protocol were suggested. This has its own problems, but would be quite flexible. I was keen to keep things like this out of indirection blocks, though.

The protocol was never progressed, partly because it was a harder sell when the help protocol already existed (and was already under used by application authors and users), and partly because it was another system that would need supporting and added to the maintenance of existing applications. Additionally, there was the very strong argument that if your 'icon' did not provide an obvious representation of the action it performed, it was not doing its job very well.

It does have merits, however, and I was hopeful we could return to it. As the core issue is one of applications not providing useful feedback, this could be addressed by making !Help more accessible. There had been a little work done by Acorn in the Style Guide and their applications to move operations from F1 so that it could be used as a general 'help' key. This had not been followed through by many other applications, so it still had a barrier blocking its use in that way.

Alerter protocol

Around the middle of Select 3 development we had found enough cases where it would have been useful to have an out-of-band notification. We were concerned mostly with a notification interface that could be used by both applications, to indicate that attention was required, but which did not need immediate attention (as might be provided by a system modal error box), or background components which needed to communicate a change in state for which there was no front end component.

Typical examples might be an application wanting to highlight a download completion, timed event, inability to connect to a background service, or other non-critical but useful information events. Similar notifications from background processes such as the acquisition (or loss) of network connectivity, new drives becoming available, or other events, could also be provided in the same way.

Ian Jeffray designed a protocol for providing notifications which could be extended in the future for other uses, and which did not focus on a particular implementation. An example notification application was also created to demonstrate a possible way that the events could be delivered. The implementation also trialled a simple system of sound themes, which allowed event classes to be tied to different sounds. The sound themes were quite flexible, but less well tied down than the general implementation of the Alerter protocol.

It was my intention to begin using the Alerter protocol for events like DHCP leases and cable notifications, as these were sufficiently simple and useful as to provide a good example area for the system. This would then be extended to other events such as those generated by !Alarm, and maybe the background error notifications. I wasn't completely sure about the background errors, as I had other plans for their reporting, but as a stop gap it might help.

It would also have allowed simple TaskWindow operations to communicate with users, where otherwise they might not have any interface to communicate through. I had already toyed with the idea of a 'low disc space' and 'low memory free' notification, but neither particularly appealed as a core system indication. Both were probably better provided as third party options - leaving them unprovided by default would free up my time to do other things, and give others an opportunity to fill that gap, and thus learn how to write such things. Of course, there were other - more functionally useful - areas that such Alerts might be useful, like notifications of failed hardware (over temperature, not responding correctly, etc) or failing peripherals (for example SMART indications).

In theory you could write a chat application where messages from others were entirely Alerter messages. Not that that's a particularly good example but it would certainly make for an interesting use.

The Alerter protocol might not have solved all the notifications and could never fill every gap, but it would have made for a more standardised out-of-band communication, and one which was replaceable. The replaceability was important, as I am certain that - like !Help - the supplied implementation, whatever it might be, would not be to everyone's taste.

Drag and Drop

There had been some work done to add clipboard support to the desktop in earlier Select releases, but one of the areas that made RISC OS productive was the ability to drag files and selections around. Whilst I had done work previously as patches to allow text fields to be dragged around the desktop, these had not been made a part of the core features of the WindowManager.

Being able to drag the selection between icons might have limited appeal, but it was an area that should be expected to work, in much the same way that dragging files worked. Some parts of the implementation would be more interesting - for example, dragging a text field to a Filer window should save the content as a text file. What the file was called might need a little thought, but it should be made to work.

Similarly, dropping a text file on to an icon should insert the content (possibly just the first line) into that icon. It follows from the automatic conversion performed by the ImageFileRender stack that content dragged to a text field should be converted from whatever format it was, into text. This might require a more generalised conversion system - I had designed a generalised file conversion system back in the FidoNet days, after much discussion with Niall Douglas. I doubt that that system would have been used, but the way that the ImageFileRender stack works could be applied to other formats.

It should be expected that a web browser (such as, say, !Mozilla) would offer to save the selection as HTML by default. It might also be able to save as text - the Drag and Drop protocols allow for different formats to be offered - but a generalised conversion system might allow applications that cannot convert formats to do so thought a single interface.

Of course, having a means by which HTML (for example) could be converted to plain text would also allow the clipboard operations that pasted HTML content into text fields to perform an implicit conversion.

!Paint had been updated to support reordering the sprites within a sprite file by dragging. This could have been updated so that if the drag left the window, it would allow the sprite to be saved out to other files. Obviously, the sprite would return to its original logical location in the file. Being able to drag sprites out of !Paint like this would make it even more like a Filer window.

Similarly, dragging !Draw objects out of the window should have been able to save them out as a DrawFile. Dropping into another !Draw window would allow the objects to be placed carefully within the target. Dropping into a Filer window would obviously create a new file, and dropping on a different application like !Paint could either offer to export as different filetypes, and allow !Paint to select the most suitable, or only as DrawFile and !Paint would automatically convert to a Sprite through ImageFileConvert. It would be better if !Draw offered different types, as that would allow !Paint to respond appropriately and indicate that it was could accept the drop.

One problem with allowing objects to be dragged out of their source window is that if the source window supports auto-scrolling, the window would scroll, rather than understanding that the user was trying to perform an operation outside the window. There are a few ways of dealing with this, but the most obvious that springs to mind is to utilise the pause time for the auto-scroll to indicate that a scroll within the window is required.

If the pointer does not pause in the edge regions, the auto-scroll does not begin, and the pointer is assumed to be operating outside the window. A consequence of this is that the pause time should be longer by default - users should expect to be able to drag objects out of the window. A default pause time of 0 to indicate that there is no pause would mean that the drags would always scroll the window.

This would also allow other applications to enable auto-scroll for their windows as the destination when a Dragging message was received. It is likely that the SWI Wimp_AutoScroll behaviour might need to change a little to ensure that it copes when the task requesting the auto-scroll is not the task that initiated the drag, and to disable the auto-scroll behaviour if the pointer leaves the window before the pause time has elapsed.