Skip to content

Add Desktop Shortcuts with App-to-App Actions and Folders#695

Open
timgerstel wants to merge 68 commits intov3.x/stagingfrom
enhancement/desktopIcons
Open

Add Desktop Shortcuts with App-to-App Actions and Folders#695
timgerstel wants to merge 68 commits intov3.x/stagingfrom
enhancement/desktopIcons

Conversation

@timgerstel
Copy link
Copy Markdown
Contributor

@timgerstel timgerstel commented Mar 13, 2026

Proposed changes

This PR introduces a full desktop shortcut and folder system to the Zowe Virtual Desktop, bringing a familiar desktop paradigm for organizing, launching, and managing applications.

This PR depends upon the following PRs:

Summary

Icons are highlightable, rearrangeable, renameable, and removable from the desktop via context menu. Shortcuts support app-to-app action requests — for example, a shortcut can open a dataset in the Rocket Software Utility Pack for Zowe File Manager.

29 files changed, ~5,100 lines added across 12 new components/services and 17 modified files.


Features

Desktop Shortcuts

  • Add app shortcuts to the desktop from the launchbar or launch menu
  • Drag to rearrange on a responsive grid that resizes with the viewport
  • Right-click context menu with rename, delete, pin to taskbar, and properties
  • Duplicate shortcut labels are auto-suffixed ("App (2)", "App (3)")
  • Undo deletions — restores shortcut metadata and grid position (up to 10 levels)
  • User icon size preference is respected

Action Shortcuts

  • Shortcuts that invoke app-to-app dispatcher actions with specific context
  • Example: launch TN3270 with a session config, or open Editor with a specific file path

Create New File

  • Desktop context menu option to create a new file shortcut linked to the Zowe Editor
  • Relies on zlux-editor#368

Desktop Folders

  • Drag shortcuts onto each other to create folders with a preview grid of child icons
  • Drag shortcuts into and out of folders
  • Inline rename of folder titles (click title to edit)
  • Duplicate folder names are auto-suffixed
  • Long folder names are truncated with ellipsis and show full name on hover tooltip
  • Folder UI correctly layers below the Zowe preferences panel

Shortcut Properties Dialog

  • View and edit icon URL and launch metadata
  • Custom icon URL input with validation (blocks javascript:/data: schemes, path traversal, HTML injection)
  • Reset button restores default plugin icon
  • Displays plugin version

Keyboard Navigation

  • Arrow keys to move selection across the desktop grid
  • Cmd/Ctrl + Arrow keys for multi-select
  • Enter to launch shortcuts or open folders
  • Delete/Backspace to remove selected shortcuts
  • F2 to rename
  • Ctrl/Cmd+A to select all
  • Escape to close folders, properties dialog, and deselect

Multi-Select & Marquee Selection

  • Cmd/Ctrl+click to toggle individual selections
  • Rubber-band drag (marquee) to select multiple items with fade-out animation
  • Multi-drag: drag multiple selected items together

Pin to Taskbar

  • Pin folders to the launchbar from the context menu
  • Launchbar folder icon shows preview grid of child app icons

Shipped Start Menu Folders

  • Plugins can ship folder definitions containing links and app shortcuts that appear in the launch menu
  • zlux-app-server#360 scans registered plugins for config/startMenuFolders/folders.json and copies them to instance storage, which is then picked up by StartMenuFoldersService via the config service

Shipped Start Menu Folders — Plugin Authors

To add folders with links or app shortcuts to the start menu, a plugin needs a folders.json inside a config/startMenuFolders/ directory at the plugin root:

{
  "folders": [
    {
      "name": "My Folder Name",
      "items": [
        {
          "type": "link",
          "dest": "https://example.com",
          "title": "Example Link"
        },
        {
          "type": "app",
          "id": "org.zowe.some.plugin",
          "title": "Launch Some App"
        }
      ]
    }
  ]
}
  • type: "link" opens URLs in a new browser tab
  • type: "app" launches a Zowe app (accepts app2app data)

Security

  • Custom icon URLs are validated and sanitized at four layers: write, load, render, and UI input
  • Blocked schemes: javascript:, vbscript:, data:
  • Blocked patterns: path traversal (../), HTML injection characters, hex-encoded control characters, null bytes, punycode domains, unknown URL schemes

New Files

File Purpose
desktop-shortcuts.service.ts Central state management — CRUD, persistence, undo stack, sanitization
start-menu-folders.service.ts Loads shipped plugin folder definitions via config service
desktop-icon.component.* Individual desktop shortcut icon (drag, select, rename, context menu)
desktop-folder.component.* Collapsed + expanded folder view with child grid, inline rename
shortcut-properties.component.* Properties dialog for shortcut metadata and custom icons
launchbar-folder-icon.component.* Pinned folder icon on the launchbar with preview grid

Modified Files

File Changes
window-pane.component.ts Desktop orchestrator — grid layout, drag/drop, marquee, keyboard nav, context menus
window-pane.component.html/css Desktop grid container, marquee overlay, shortcut/folder host elements
launchbar-menu.component.* Combined entries (apps + user folders + shipped folders + shipped items) in launch menu
launchbar.component.* Renders pinned folders, passes folder data to menu
context-utils.ts Shared context menu builder for shortcut actions
window-manager.service.ts Desktop focus management
window-manager.module.ts Module declarations for new components and services
pluginDefinition.json Start menu folder resource declarations

Known Limitations / Future Work

  • Sorting options (by name, date, type) not yet implemented
  • No automated unit tests for the new components (manual QA test plan exists)

default.mov
Desktop shortcuts and folders overview Context menu and folder creation Shortcut properties dialog Launch menu with shipped folders Keyboard navigation and multi-select Start menu folders

Type of change

  • New feature (non-breaking change which adds functionality)

PR Checklist

  • My code follows the style guidelines of this project (see: Contributing guideline)
  • I have commented my code, particularly in hard-to-understand areas
  • video or image is included if visual changes are made
  • Relevant update to CHANGELOG.md
  • My changes generate no new warnings

Testing

Manual testing required. Key scenarios to verify:

  1. Shortcut CRUD — Add shortcuts from launchbar context menu and launch menu, rename inline (F2 or double-click label), delete via context menu or Delete key, undo deletion
  2. Drag & Drop — Rearrange shortcuts on the grid, drag onto another shortcut to create a folder, drag into/out of folders, multi-drag with Cmd/Ctrl+click selection
  3. Folders — Open folder (double-click or Enter), rename folder title by clicking it, close via X button or clicking outside, verify grid preview icons
  4. Keyboard — Arrow keys navigate grid, Enter launches, Escape dismisses UI, Cmd/Ctrl+A selects all, Cmd/Ctrl+Arrow extends selection
  5. Marquee — Click and drag on empty desktop space to rubber-band select multiple items
  6. Properties — Right-click → Properties, edit icon URL (test invalid URLs are rejected), verify plugin version
  7. Pin to Taskbar — Right-click folder → Pin to Launchbar, verify folder icon appears with preview
  8. Launch Menu — Verify shipped plugin folders appear alongside apps, folder items launch correctly
  9. Create New File — Right-click desktop → Create New File (requires Zowe Editor installed)
  10. Persistence — Refresh browser, verify shortcuts/folders/positions are preserved
  11. Preferences Panel — Open Zowe preferences while a folder is open, verify preferences panel appears on top

Further comments

This is a large feature addition (~5,100 lines) that introduces a desktop metaphor to the Zowe Virtual Desktop. The architecture centers on DesktopShortcutsService as a single source of truth using BehaviorSubject-based reactive state, with optimistic UI updates and server persistence via the Zowe config service. The undo stack supports up to 10 levels of deletion recovery.

The folder system reuses the same shortcut data model with a folderId foreign key, keeping the storage format flat and the migration path simple. Icon URL sanitization is defense-in-depth across write, load, render, and input layers.

Companion PRs:

  • zlux-app-server#360 — Scans plugins for config/startMenuFolders/ and copies folder definitions to instance storage
  • zlux-editor#368 — Handles desktop-new-file-saved events for the "Create New File" shortcut flow

…p icons are highlightable, rearrangable, and removable from the desktop via the context menu

Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
…ches a plugin (current behavior) Action shortcut — invokes a Zowe dispatcher action with specific data (e.g., open TN3270 with specific session config, open editor with a specific file path)

Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
@timgerstel timgerstel changed the title Add Desktop Icons Add Desktop Icons/Shortcuts Mar 13, 2026
…actions

Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
…scored)

Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
@timgerstel timgerstel changed the title Add Desktop Icons/Shortcuts Add Desktop Iconsand Shortcuts with App-to-App Actions Mar 13, 2026
@timgerstel timgerstel changed the title Add Desktop Iconsand Shortcuts with App-to-App Actions Add Desktop Icons and Shortcuts with App-to-App Actions Mar 13, 2026
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
@timgerstel timgerstel changed the title Add Desktop Icons and Shortcuts with App-to-App Actions Add Desktop Shortcuts and Folders with App-to-App Actions Mar 27, 2026
@timgerstel timgerstel changed the title Add Desktop Shortcuts and Folders with App-to-App Actions Add Desktop Shortcuts with App-to-App Actions and Folders Mar 27, 2026
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
@timgerstel timgerstel force-pushed the enhancement/desktopIcons branch from 76f620b to fcba038 Compare March 29, 2026 20:00
… grid space from being occupied.

Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
…select, enter to launch). add context menu option to pin shortcuts from desktop to launchbar

Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
…enhancement/desktopIcons

Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
…user interaction (keyboard nav)

Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
@timgerstel timgerstel marked this pull request as ready for review April 7, 2026 13:03
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
return this.folder?.name || 'New Folder';
}

get positionStyle(): { [key: string]: string } {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Computes absolute position for folder on desktop grid

lastOpenedDate?: string;
}

export interface DesktopFolder {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there anything else we want to track for pseudo folders? These arent folders that represent directories so things like 'size' aren't applicable.

onLogin(username:string, plugins:ZLUX.Plugin[]):boolean {
this.replaceWallpaper(DESKTOP_WALLPAPER_URI);
this.shortcutsService.loadShortcuts();
this.loadPinnedPluginIds();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed for the desktop icon context menu to know which plugins are already pinned to the taskbar.

The launchbar already owns pinnedPlugins.json so window-pane could listen to a shared observable or service rather than making its own HTTP call, but that would mean introducing a dependency between window-pane and the launchbar's data service, which are currently decoupled. This approach trades one extra GET for simpler component boundaries

…by the desktop shortcuts service and then santized

Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
…l title tooltip with full name

Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Comment thread CHANGELOG.md Outdated
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Copy link
Copy Markdown
Member

@1000TurquoisePogs 1000TurquoisePogs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

@github-project-automation github-project-automation Bot moved this from Ready for Review to Merge Ready in WebUI planning board Apr 15, 2026
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
…enhancement/desktopIcons

Signed-off-by: Timothy Gerstel <tim.gerstel@gmail.com>
@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Merge Ready

Development

Successfully merging this pull request may close these issues.

2 participants