Workbench and icon.library V44–V47 for Developers¶
AmigaOS 3.2 ships workbench.library 47 and icon.library 47. Together with the V44/V45 API that was introduced for OS 3.5/3.9 and is now part of the official 3.2 NDK, they give applications much more than the V37 trio of AppWindow, AppIcon and AppMenuItem: drop zones, AppIcons that answer the "Icons" menu, sub-menus in the Tools menu, programmatic drawer opening, copy/delete/rename hooks, a hit-test for Workbench objects, file-type identification through DefIcons, and outlined/shadowed icon labels.
This article is a developer's map of that API, built from workbench/workbench.h, workbench/icon.h, workbench/startup.h, prefs/workbench.h, the autodocs and the release notes. For per-function autodoc text see workbench.library Reference and icon.library Reference.
workbench.library functions¶
| LVO | Function | Since |
|---|---|---|
| −30 | UpdateWorkbench(name, lock, action) |
V36 (made public in 45.99) |
| −48 | AddAppWindowA(id, userdata, window, msgport, tags) |
V36 |
| −54 | RemoveAppWindow(appWindow) |
V36 |
| −60 | AddAppIconA(id, userdata, text, msgport, lock, diskobj, tags) |
V36 |
| −66 | RemoveAppIcon(appIcon) |
V36 |
| −72 | AddAppMenuItemA(id, userdata, text, msgport, tags) |
V36 |
| −78 | RemoveAppMenuItem(appMenuItem) |
V36 |
| −90 | WBInfo(lock, name, screen) |
V39 |
| −96 | OpenWorkbenchObjectA(name, tags) |
V44 |
| −102 | CloseWorkbenchObjectA(name, tags) |
V44 |
| −108 | WorkbenchControlA(name, tags) |
V44 |
| −114 | AddAppWindowDropZoneA(aw, id, userdata, tags) |
V44 |
| −120 | RemoveAppWindowDropZone(aw, dropZone) |
V44 |
| −126 | ChangeWorkbenchSelectionA(name, hook, tags) |
V44 |
| −132 | MakeWorkbenchObjectVisibleA(name, tags) |
V44 |
| −138 | WhichWorkbenchObjectA(window, x, y, tags) |
V47 |
RemoveAppWindow(), RemoveAppIcon() and RemoveAppMenuItem() return a BOOL since workbench.library 44.99; the release notes say they used to return the pointer passed in. All Add… calls need a running Workbench (LoadWB executed and the screen open), and return NULL otherwise. All workbench.library tags use the base WBA_Dummy = TAG_USER + 0xA000.
AppMessages¶
struct AppMessage {
struct Message am_Message;
UWORD am_Type; /* AMTYPE_* */
ULONG am_UserData;
ULONG am_ID;
LONG am_NumArgs;
struct WBArg *am_ArgList;
UWORD am_Version; /* >= AM_VERSION (1) */
UWORD am_Class; /* AMCLASSICON_* for AppIcons (V44) */
WORD am_MouseX, am_MouseY;
ULONG am_Seconds, am_Micros;
ULONG am_Reserved[8];
};
am_Type |
Value | Sent for |
|---|---|---|
AMTYPE_APPWINDOW 3.1+ |
7 | icons dropped on an AppWindow (outside any drop zone) |
AMTYPE_APPICON 3.1+ |
8 | AppIcon opened, dropped on, or menu action |
AMTYPE_APPMENUITEM 3.1+ |
9 | Tools menu item selected |
AMTYPE_APPWINDOWZONE 3.2+ |
10 | icons dropped on a drop zone (V44) |
Reply every AppMessage quickly. Workbench is waiting on them. Since workbench.library 45.134, an AppMessage that cannot be delivered to an AppIcon or AppWindow is freed by Workbench instead of "hanging around till the next reboot".
AppIcons¶
AddAppIconA() tags (all BOOL unless shown):
| Tag | Value | Default | Effect |
|---|---|---|---|
WBAPPICONA_SupportsOpen 3.2+ |
+1 | TRUE | responds to "Open" |
WBAPPICONA_SupportsCopy 3.2+ |
+2 | FALSE | "Copy" |
WBAPPICONA_SupportsRename 3.2+ |
+3 | FALSE | "Rename" |
WBAPPICONA_SupportsInformation 3.2+ |
+4 | FALSE | "Information" |
WBAPPICONA_SupportsSnapshot 3.2+ |
+5 | FALSE | "Snapshot" |
WBAPPICONA_SupportsUnSnapshot 3.2+ |
+6 | FALSE | "UnSnapshot" |
WBAPPICONA_SupportsLeaveOut 3.2+ |
+7 | FALSE | "Leave Out" |
WBAPPICONA_SupportsPutAway 3.2+ |
+8 | FALSE | "Put Away" |
WBAPPICONA_SupportsDelete 3.2+ |
+9 | FALSE | "Delete" |
WBAPPICONA_SupportsFormatDisk 3.2+ |
+10 | FALSE | "Format Disk" |
WBAPPICONA_SupportsEmptyTrash 3.2+ |
+11 | FALSE | "Empty Trash" |
WBAPPICONA_SupportsEjectDisk 3.2+ |
+158 | FALSE | "Eject Disk" (V47) |
WBAPPICONA_PropagatePosition 3.2+ |
+12 | FALSE | write position back to your DiskObject (you must keep it) |
WBAPPICONA_RenderHook 3.2+ |
+13 | NULL | struct Hook * called to render the icon |
WBAPPICONA_NotifySelectState 3.2+ |
+14 | FALSE | get AMCLASSICON_Selected/Unselected messages |
(Values are offsets from WBA_Dummy.) The menu action arrives in am_Class:
am_Class |
Value | am_Class |
Value | |
|---|---|---|---|---|
AMCLASSICON_Open 3.5+ |
0 | AMCLASSICON_PutAway |
7 | |
AMCLASSICON_Copy 3.2+ |
1 | AMCLASSICON_Delete |
8 | |
AMCLASSICON_Rename 3.2+ |
2 | AMCLASSICON_FormatDisk |
9 | |
AMCLASSICON_Information 3.2+ |
3 | AMCLASSICON_EmptyTrash |
10 | |
AMCLASSICON_Snapshot 3.2+ |
4 | AMCLASSICON_Selected |
11 | |
AMCLASSICON_UnSnapshot 3.2+ |
5 | AMCLASSICON_Unselected |
12 | |
AMCLASSICON_LeaveOut 3.2+ |
6 | AMCLASSICON_EjectDisk |
13 |
AMCLASSICON_Open covers a double-click, the "Open" menu item and icons dropped on the AppIcon. The render hook is called as LONG hookFunc(struct Hook *hook, APTR reserved, struct AppIconRenderMsg *arm) (A0/A2/A1). Return TRUE to have the normal image drawn as well. Combined with WorkbenchControl(NULL, WBCTRLA_RedrawAppIcon, appIcon, TAG_DONE) this gives animated AppIcons.
AppMenuItems, sub-menus and new menus¶
| Tag | Value | Type | Since |
|---|---|---|---|
WBAPPMENUA_CommandKeyString 3.2+ |
+15 | STRPTR | V44 (first character only; ignored if already used) |
WBAPPMENUA_GetKey 3.2+ |
+65 | ULONG * |
V44 (workbench.library 44.1511+) |
WBAPPMENUA_UseKey 3.2+ |
+66 | ULONG | V44; with a title key, V45 |
WBAPPMENUA_GetTitleKey 3.2+ |
+77 | ULONG * |
V45 |
A label made only of -, _ or ~ characters becomes a separator bar (V44). A menu that already holds 63 items refuses new ones. To build a sub-menu, add the parent item with WBAPPMENUA_GetKey, then add its children with WBAPPMENUA_UseKey:
ULONG key;
struct AppMenuItem *parent, *a, *b;
parent = AddAppMenuItem(0, 0, "My Tool", port, WBAPPMENUA_GetKey, &key, TAG_DONE);
a = AddAppMenuItem(1, 0, "Do this", port, WBAPPMENUA_UseKey, key,
WBAPPMENUA_CommandKeyString, "T", TAG_DONE);
b = AddAppMenuItem(2, 0, "Do that", port, WBAPPMENUA_UseKey, key, TAG_DONE);
WBAPPMENUA_GetTitleKey does the same one level up: it creates a new menu title in the Workbench strip that later items attach to.
AppWindows and drop zones¶
Without drop zones, an icon dropped anywhere in an AppWindow produces an AMTYPE_APPWINDOW message. AddAppWindowDropZoneA() (V44) marks areas instead. Once a zone exists, drops on it arrive as AMTYPE_APPWINDOWZONE with am_ID/am_UserData set to the zone's values. Removing the AppWindow removes all its zones.
| Tag | Value | Type | Meaning |
|---|---|---|---|
WBDZA_Left / WBDZA_RelRight |
+26 / +27 | WORD | left edge, absolute or relative to the right window edge |
WBDZA_Top / WBDZA_RelBottom |
+28 / +29 | WORD | top edge, absolute or relative to the bottom |
WBDZA_Width / WBDZA_RelWidth |
+30 / +31 | WORD | width, absolute or relative to window width |
WBDZA_Height / WBDZA_RelHeight |
+32 / +33 | WORD | height, absolute or relative |
WBDZA_Box 3.2+ |
+34 | struct IBox * |
position and size in one go |
WBDZA_Hook 3.2+ |
+35 | struct Hook * |
highlight hook, called on enter/leave |
The hook gets a struct AppWindowDropZoneMsg (adzm_RastPort, adzm_DropZoneBox, adzm_ID, adzm_UserData, adzm_Action = ADZMACTION_Enter 0 / ADZMACTION_Leave 1) and must return 0. Only simple graphics.library drawing is allowed inside it. The autodoc warns that refreshing gadgets or locking IntuitionBase there "will deadlock the operating system". Leaving a zone does not mean nothing will be dropped on it.
Opening drawers and launching programs¶
OpenWorkbenchObjectA(name, tags) acts as if the user double-clicked the icon (drawer, tool or project):
| Tag | Value | Type | Meaning |
|---|---|---|---|
WBOPENA_ArgLock 3.2+ |
+16 | BPTR | lock for the following WBOPENA_ArgName entries (duplicated) |
WBOPENA_ArgName 3.2+ |
+17 | STRPTR | add a WBArg for the launched program (duplicated) |
WBOPENA_Show 3.1.4+ |
+75 | UBYTE | drawer show mode: DDFLAGS_SHOWICONS / DDFLAGS_SHOWALL (V45) |
WBOPENA_ViewBy 3.1.4+ |
+76 | UBYTE | drawer view: DDVM_BYICON … DDVM_BYTYPE (V45) |
/* Launch MultiView with S:Startup-Sequence (autodoc example) */
BPTR dir = Lock("S:", SHARED_LOCK);
OpenWorkbenchObject("MultiView",
WBOPENA_ArgLock, dir,
WBOPENA_ArgName, "Startup-Sequence",
TAG_DONE);
UnLock(dir); /* Workbench duplicated it */
TRUE may be returned even if the program could not actually be started. CloseWorkbenchObjectA() closes a drawer window, and MakeWorkbenchObjectVisibleA() scrolls a drawer so that an icon is visible. Workbench 47.19 reworked drawer opening so that OpenWorkbenchObjectA() sets up the same internal state as a real double-click.
Drawer icons gained a V47 sort order in DrawerData.dd_Flags: DDFLAGS_SORTMASK 0x300, DDFLAGS_SORTDEFAULT 0, DDFLAGS_SORTASC 0x100, DDFLAGS_SORTDESC 0x200. It is saved with the drawer at snapshot time.
WorkbenchControlA¶
BOOL WorkbenchControlA(STRPTR name, struct TagItem *tags) queries and changes Workbench options. On FALSE, IoErr() has the reason. It may only be called by a Process.
| Tag | Value | Data | Since |
|---|---|---|---|
WBCTRLA_IsOpen 3.2+ |
+18 | LONG * |
V44 — is drawer name open? |
WBCTRLA_DuplicateSearchPath / …FreeSearchPath |
+19 / +20 | BPTR * / BPTR |
V44 |
WBCTRLA_GetDefaultStackSize / …Set… |
+21 / +22 | ULONG * / ULONG |
V44 |
WBCTRLA_RedrawAppIcon 3.2+ |
+23 | struct AppIcon * |
V44 |
WBCTRLA_GetProgramList / …FreeProgramList |
+24 / +25 | struct List ** / * |
V44 |
WBCTRLA_GetSelectedIconList / …Free… |
+36 / +37 | struct List ** / * |
V44 |
WBCTRLA_GetOpenDrawerList / …Free… |
+38 / +39 | struct List ** / * |
V44 |
WBCTRLA_GetHiddenDeviceList / …Free… |
+42 / +43 | struct List ** / * |
V44 |
WBCTRLA_AddHiddenDeviceName / …Remove… |
+44 / +45 | STRPTR | V44 |
WBCTRLA_GetTypeRestartTime / …Set… |
+47 / +48 | ULONG * / ULONG |
V44 |
WBCTRLA_GetCopyHook / …SetCopyHook |
+69 / +70 | struct Hook ** / * |
V45 |
WBCTRLA_GetDeleteHook / …SetDeleteHook |
+71 / +72 | struct Hook ** / * |
V45 |
WBCTRLA_GetTextInputHook / …Set… |
+73 / +74 | struct Hook ** / * |
V45 |
WBCTRLA_AddSetupCleanupHook / …Rem… |
+78 / +79 | struct Hook * |
V45 |
WBCTRLA_SetGlobalFlags / …GetGlobalFlags |
+130 / +131 | ULONG / ULONG * |
V47 |
WBCTRLA_GetDiskInfoHook / …SetDiskInfoHook |
+159 / +160 | struct Hook ** / * |
V47 |
With Workbench closed, only the stack size, hidden-device and type-restart tags (V44), plus the copy/delete/text-input hook tags (V45), are processed.
V47 global flags¶
#define WBF_DRAWERPOSMASK 0x00000003 /* Drawer placement mask (text mode) */
#define WBF_DRAWERPOSFREE 0x00000000 /* Place drawers mixed with files */
#define WBF_DRAWERPOSHEAD 0x00000001 /* Place drawers at top of list */
#define WBF_DRAWERPOSTAIL 0x00000002 /* Place drawers at bottom of list */
#define WBF_BOUNDTEXTVIEW 0x00000080 /* Limit scrolling in text mode drawers */
#define WBF_OLDDATESFIRST 0x00010000 /* Reverse default ordering of dates */
The release notes say that, at the time, WBF_BOUNDTEXTVIEW and the date ordering had no control in the Workbench editor: "it can only be changed programmatically via WorkbenchControlA() for now". Always read-modify-write:
ULONG flags;
if (WorkbenchControl(NULL, WBCTRLA_GetGlobalFlags, &flags, TAG_DONE))
WorkbenchControl(NULL, WBCTRLA_SetGlobalFlags,
(flags & ~WBF_DRAWERPOSMASK) | WBF_DRAWERPOSHEAD
| WBF_BOUNDTEXTVIEW, TAG_DONE);
Disk-info hook (V47)¶
Workbench calls this hook when a disk is unreadable to the handler (for example an MS-DOS disk in a trackdisk drive): state = hookFunc(hook, info, msgport) with A0/A2/A1, where info is the struct InfoData * the handler already filled in and msgport is the handler's port. Return info->id_DiskState to keep the "Unreadable" icon, or ID_NO_DISK_PRESENT to hide it. Passing NULL restores the default. The hook cannot be replaced while it is in use (ERROR_OBJECT_IN_USE). These tags were renumbered during 3.2 development, so build with the final headers.
Hook message types¶
| Hook | Message(s) | Actions |
|---|---|---|
| Copy | CopyBeginMsg, CopyDataMsg, CopyEndMsg |
CPACTION_Begin 0, _Copy 1, _End 2 |
| Delete | DeleteBeginMsg, DeleteDataMsg, DeleteEndMsg |
DLACTION_BeginDiscard 0, _BeginEmptyTrash 1, _DeleteContents 3, _DeleteObject 4, _End 5 |
| Text input | TextInputMsg |
TIACTION_Rename 0, _RelabelVolume 1, _NewDrawer 2, _Execute 3 |
| Setup/cleanup | SetupCleanupHookMsg |
SCHMSTATE_TryCleanup 0, _Cleanup 1, _Setup 2 |
Copying is never sent to the copy hook when data can be moved by a simple rename, or when DiskCopy duplicates a whole volume. For DLACTION_DeleteContents you empty the drawer but do not delete the drawer itself.
WhichWorkbenchObjectA (V47)¶
ULONG WhichWorkbenchObjectA(struct Window *window, LONG x, LONG y,
const struct TagItem *tags);
This returns WBO_ICON (2) if a click at x,y would hit a visible Workbench icon, WBO_DRAWER (1) for a visible part of a Workbench drawer window with no icon there, and WBO_NONE (0) otherwise. Coordinates are window-relative, or screen-relative with a NULL window, in which case the topmost window is used. Information tags (all offsets from WBA_Dummy): WBOBJA_Type +86, _Left +87, _Top +88, _Width +89, _Height +90, _State +91, _IsFake +92, _Name/_NameSize +93/+94 (default 64), _FullPath/_FullPathSize +95/+96 (default 512), _IsLink +97, _DrawerPath/_DrawerPathSize +98/+99, _DrawerFlags +116, _DrawerModes +117. Only trust icon tags after WBO_ICON and drawer tags after WBO_DRAWER or WBO_ICON.
The function is meant for input helpers such as commodities, for example a ClickToFront that should ignore double-clicks on icons, or context menus. "Usage of this function by normal applications is discouraged."
UpdateWorkbench¶
UpdateWorkbench(name, parentLock, action) tells Workbench that an object appeared or changed (UPDATEWB_ObjectAdded 1) or was deleted (UPDATEWB_ObjectRemoved 0). Call it after writing or deleting files that may be shown in an open drawer. Since 47.11 Workbench detects links added this way and shows them with an underlined label, under their own name rather than the target's.
Workbench preferences (prefs/workbench.h)¶
| Chunk | Structure | Content |
|---|---|---|
WBNC |
WorkbenchPrefs / WorkbenchExtendedPrefs |
stack size, type restart time, icon precision, emboss rect, borderless, max name length, NewIcons/colour icons; V45 extensions (lock pens, disable title bar / volume gauge); V47 wbe_TitleUpdateDelay (ms), wbe_CopyBufferSize, wbe_Flags |
WBHD |
WorkbenchHiddenDevicePrefs |
one NUL-terminated device name per chunk |
WBTF |
WorkbenchTitleFormatPrefs |
the screen title format string (V47) |
Title Format Items¶
The Workbench screen title is configurable (workbench.library 46.1+). The string may hold text and these items:
| Item | Meaning |
|---|---|
%e <envname> |
value of an environment variable |
%m + type + block + unit |
memory: type c chip / f fast; block e free, u used, t total, l largest; unit b bytes, k KB, m MB, q percent of total. Example: %mcuq = chip memory in use as % of total |
%vk, %vw |
Kickstart revision, Workbench version |
%c, %f |
CPU, FPU |
%r |
release version information (from the Versions/Release variable) |
%i + p/s/d/i/r/a |
default public screen name, number of screens, active drawer name, selected icons, running programs, active disks |
Users edit this in the Workbench preferences editor, which has a helper for inserting items. Programs should not depend on the title's contents.
icon.library V44–V47¶
| LVO | Function |
|---|---|
| −144 | FreeFree(fl, address) |
| −150 | DupDiskObjectA(diskObject, tags) |
| −156 | IconControlA(icon, tags) |
| −162 | DrawIconStateA(rp, icon, label, left, top, state, tags) |
| −168 | GetIconRectangleA(rp, icon, label, rect, tags) |
| −174 | NewDiskObject(type) |
| −180 | GetIconTagList(name, tags) |
| −186 | PutIconTagList(name, icon, tags) |
| −192 | LayoutIconA(icon, screen, tags) |
| −198 | ChangeToSelectedIconColor(cr) |
| −204 | BumpRevisionLength(newname, oldname, maxLength) (V45) |
Tag base: ICONA_Dummy = TAG_USER + 0x9000.
File-type identification: ICONGETA_IdentifyBuffer (V47)¶
| Tag | Value | Type | Meaning |
|---|---|---|---|
ICONGETA_IdentifyBuffer 3.2+ |
+122 | STRPTR | buffer of at least 256 bytes that receives the file type from the global identification hook, even if the file has a real icon |
ICONGETA_IdentifyOnly 3.2+ |
+123 | BOOL | with a valid buffer: do not load an icon at all; GetIconTagList() returns NULL with error code 0 |
- Only works for files (tools and projects), not volumes, drawers or trashcans.
- An unidentified file leaves an empty string in the buffer.
- Needs DefIcons 47.8 or later, which installs the identification hook (
ICONCTRLA_SetGlobalIdentifyHook). DefIcons also offers the same through its ARexx portDEFICONSwith the commandIdentify NAME/A.
Example: AppWindow that identifies dropped files¶
#include <exec/types.h>
#include <workbench/workbench.h>
#include <workbench/icon.h>
#include <workbench/startup.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/wb.h>
#include <proto/icon.h>
struct IntuitionBase *IntuitionBase;
struct Library *WorkbenchBase, *IconBase;
static void identify(struct WBArg *arg)
{
UBYTE type[256];
LONG err = 0;
BPTR old = CurrentDir(arg->wa_Lock);
type[0] = '\0';
GetIconTags(arg->wa_Name,
ICONGETA_IdentifyBuffer, type,
ICONGETA_IdentifyOnly, TRUE,
ICONA_ErrorCode, &err,
TAG_DONE); /* returns NULL by design */
CurrentDir(old);
Printf("%s: %s\n", arg->wa_Name, type[0] ? (char *)type : "(unknown)");
}
int main(void)
{
struct MsgPort *port;
struct Window *win;
struct AppWindow *aw;
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39);
WorkbenchBase = OpenLibrary("workbench.library", 44);
IconBase = OpenLibrary("icon.library", 47);
if (IntuitionBase && WorkbenchBase && IconBase &&
(port = CreateMsgPort()))
{
win = OpenWindowTags(NULL, WA_Title, "Drop files here",
WA_Width, 300, WA_Height, 120, WA_DragBar, TRUE,
WA_CloseGadget, TRUE, WA_DepthGadget, TRUE,
WA_IDCMP, IDCMP_CLOSEWINDOW, TAG_DONE);
if (win && (aw = AddAppWindow(1, 0, win, port, TAG_DONE)))
{
ULONG wsig = 1UL << win->UserPort->mp_SigBit;
ULONG asig = 1UL << port->mp_SigBit;
BOOL done = FALSE;
struct Message *m;
while (!done)
{
ULONG s = Wait(wsig | asig | SIGBREAKF_CTRL_C);
if (s & SIGBREAKF_CTRL_C) done = TRUE;
while ((m = GetMsg(port)))
{
struct AppMessage *am = (struct AppMessage *)m;
LONG i;
for (i = 0; i < am->am_NumArgs; i++)
identify(&am->am_ArgList[i]);
ReplyMsg(m);
}
while ((m = GetMsg(win->UserPort)))
{
if (((struct IntuiMessage *)m)->Class == IDCMP_CLOSEWINDOW)
done = TRUE;
ReplyMsg(m);
}
}
RemoveAppWindow(aw);
/* drain AppMessages that arrived meanwhile */
while ((m = GetMsg(port))) ReplyMsg(m);
}
if (win) CloseWindow(win);
DeleteMsgPort(port);
}
if (IconBase) CloseLibrary(IconBase);
if (WorkbenchBase) CloseLibrary(WorkbenchBase);
if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
return 0;
}
Each WBArg is a lock plus a name relative to it, which is why the example calls CurrentDir() before GetIconTags(). Dropped drawers and disks are not identified, as noted above.
Outlined and shadowed labels (V47)¶
| Tag | Value | Type |
|---|---|---|
ICONDRAWA_LabelShadow 3.2+ |
+93 | BOOL — draw the label with a shadow |
ICONDRAWA_LabelOutline 3.2+ |
+94 | BOOL — draw the label with an outline |
icon.library 47.3 / workbench.library 47.13 added these for DrawIconStateA(). The release note says the background colour is used for the outline/shadow, the icon font settings must be in normal text mode, and the user enables it on Workbench with the WBCtrl commands LABELSHADOW or LABELOUTLINE. Pass these tags on (together with arm_Tags) if your AppIcon render hook calls DrawIconStateA() itself, so that your icon matches the others.
ICONDRAWA_IsLink (+89) draws a link's label underlined; Workbench uses it for soft links.
Icon file name rules¶
ICONCTRLA_SetGlobalMaxNameLengthsets the file name limit icon.library applies, in the range 8–255, default 25. If an icon name would exceed it,PutIconTagList()silently pretends success, to avoid overwriting the data file with the icon file. PassICONA_ErrorCodeto see this: the error isERROR_TOO_MANY_LEVELS.- The 45.20 release note gives the maximum file name size as 106 characters, so 101 for the base name plus
.info. New icons must end in the full.infosuffix, not a truncated one. - Since 47.2, writing an icon through a soft link (for example to make
RAM:Disk.infochanges permanent) is no longer mistaken for name truncation. BumpRevisionLength(newbuf, oldname, maxLength)(V45) builds "copy_of_…" names with a length limit and returns NULL when even a truncated name will not fit. It replaces the unboundedBumpRevision(), which could overflow its buffer.
Starting from Workbench: WBStartup¶
A program started by Workbench receives a struct WBStartup message, and every argument in it is a struct WBArg:
struct WBStartup {
struct Message sm_Message; /* a standard message structure */
struct MsgPort *sm_Process; /* the process descriptor for you */
BPTR sm_Segment; /* a descriptor for your code */
LONG sm_NumArgs; /* the number of elements in ArgList */
STRPTR sm_ToolWindow;/* description of window */
struct WBArg *sm_ArgList; /* the arguments themselves */
};
struct WBArg { BPTR wa_Lock; STRPTR wa_Name; }; /* name relative to lock */
The same WBArg pair appears in AppMessages (am_ArgList) and is what WBOPENA_ArgLock/WBOPENA_ArgName build when you launch a program with OpenWorkbenchObjectA(). When a tool is launched from a project icon, Workbench now reads the tool's own icon to get its stack size, instead of falling back to a default when the project has none (45.134). 47.20 fixed this for default tools given as a relative path.
See Also¶
- workbench.library Reference
- icon.library Reference
- Intuition V47 BOOPSI and Input Extensions
- ReAction Examples Guide (Backfill and ToolManagerPrefs use AppWindows)
- AmigaOS 3.2 — What Changed for Developers
Sources: NDK 3.2 R4 Include_H/workbench/{workbench.h,icon.h,startup.h}, Include_H/prefs/workbench.h, SFD/wb_lib.sfd, SFD/icon_lib.sfd, FD/wb_lib.fd, FD/icon_lib.fd, Autodocs/wb.doc, Autodocs/icon.doc, ReleaseNotes/{wb,icon,Workbench,DefIcons}-RelNotes Updated: 2026-11-13