Customizing Jump List of UWP App

Jump List of Fitbit UWP Application.

What is Jump List?

Jump list is a feature to access app's action quickly by right-clicking the icon of the app (from taskbar or start menu). Recent (or frequently) opened file with that app, or the shortcut of app's main feature mainly comes here. You can learn more about jump list here.

This feature has been introduced in Windows 7. You can use this in Win32 application, of course, and also you can still use in UWP application in Windows 10. In today's post, I'll walkthrough you how to customize jump list of UWP application, by using Windows.UI.StartScreen.JumpList, one of the WinRT API.

⚠️ Wait, aren't you a developer?

This post is for developers who is editing their app to add menus manually, not for user. You cannot add or manage custom jump list menus if the app dosen't support the feature. If you want to use jump list in those app, please ask to that app's developer to add the feature.

 

Type of menus can be managed at jump list

There are two kinds of jump list items: system group and user group.

Item displaying in system group at jump list.

Item displaying in system group at jump list.

System group displays automatically list of files has been opened with that app. You cannot manage this list programmatically, but you can set which list should be displayed. Frequent list, recent list or show nothing.

Some test shortcuts displaying in user group at jump list.

Some test shortcuts displaying in user group at jump list.

User group is the place where you can add custom shortcut. When adding menu, two types are available. That is, you have to choose the right type for your purpose.

Context menu of 'Quick Menu A'. User can remove this item.

Context menu of 'Quick Menu A'. User can remove this item.

Context menu of 'Quick Menu C'. Unlike menu A and B, this cannot be removed by user.

Context menu of 'Quick Menu C'. Unlike menu A and B, this cannot be removed by user.

I added four menus in test app. Quick Menu A and Quick Menu B is under 'Quick Menu'group. Quick Menu C and Quick Menu D is under 'Tasks' group. Right-clicking Quick Menu A shows that this menu can be removed. However, context menu of Quick Menu C shows that this menu is read-only.

There are five properties that can be assigned to jump list menu item. First, argument used for sorting with other menus. displayName is a value for label text. And description is for the tooltip text, groupName for group name, and logo for location of the icon image included in app resource. Using different groupName will sort in such group. When group name is assigned, those menus can be deleted by user. But when you assign empty string (""), it will have 'Tasks' for group name automatically. In this case, user won't be able to delete it.

Fitbit app's jump list. These menus are removable by user, and likely unable to restore.

Fitbit app's jump list. These menus are removable by user, and likely unable to restore.

So, how should we add menus to jump list? Menus like shortcut to features should have no value for groupName, so it can be included at 'Tasks' group. You cannot give custom group name for those items, but you can prevent users to remove from jump list (if you're not providing menus to restore them later). User-managed lists such as favorites or recently visited list should have group name to make it removable from jump list.

Looking at the Fitbit and Instagram UWP app's jump list, there are some feature shortcuts. It appears that user can delete these menus (just like screenshot above), but these menus will not come back until the app has been reset or reinstalled. Therefore, these apps are misusing the API.

 

Access to jump list

Jump list is not directly accessible. To manage jump list, you must asynchronously load the jump list.

Use Windows.UI.StartScreen.JumpList.loadCurrentAsync function to load. This is an async function.

JavaScript
var JumpList = Windows.UI.StartScreen.JumpList;
// Load current jump list.
JumpList.loadCurrentAsync().then(function (loadedJumpList) {
    // loadedJumpList is the loaded jump list.

}).done();

Now you can access jump list which is provided as an argument in returned function.

 

Changing type to display in system group

As previously stated, system group can show frequently opened items, recently opened items, or show nothing. Let's modify which mode should app display.

Use Windows.UI.StartScreen.JumpListSystemGroupKind enumeration by assigning proper mode to systemGroupKind, which is included at loaded jump list. See code below.

☝️ Memo

  • When app has no assigned file type to open, system group list will show nothing if you assign systemGroupKind to recent or frequent.
  • User group items will be accessible even if you hide the system group.
JavaScript
var JumpList = Windows.UI.StartScreen.JumpList,
    JumpListItem = Windows.UI.StartScreen.JumpListItem;
// Load current jump list.
JumpList.loadCurrentAsync().then(function (loadedJumpList) {
    // loadedJumpList is the loaded jump list.
    // Set system group display mode. We'll set to frequent mode here.
    loadedJumpList.systemGroupKind = Windows.UI.StartScreen.JumpListSystemGroupKind.frequent;
    
}).done();
 

Add shortcut menu in jump list

I will make Quick Menu A, B, C and D as shown describing user group above.

Use Windows.UI.StartScreen.JumpListItem.createWithArguments function to create new item and assign it to new variable. The function's first argument is the String value to sort with different menus. The second argument is the label of the Menu (String). Tooltip value and group name can be assigned after the new item has assigned own variable.

Push newely created items to jump list(in this code, loadedJumpList) by items.append function.

JavaScript
var JumpList = Windows.UI.StartScreen.JumpList,
    JumpListItem = Windows.UI.StartScreen.JumpListItem;
// Load current jump list.
JumpList.loadCurrentAsync().then(function (loadedJumpList) {
    // loadedJumpList is the loaded jump list.
    // Set system group display mode. We'll set to frequent mode here.
    loadedJumpList.systemGroupKind = Windows.UI.StartScreen.JumpListSystemGroupKind.frequent;
    // Assign group name 'Quick Menu' to Quick Menu A and Quick Menu B.
    var itemA = JumpListItem.createWithArguments("quickMenuA", "Quick Menu A");
    itemA.description = "Description of Quick Menu A";
    itemA.groupName = "Quick Menu";
    var itemB = JumpListItem.createWithArguments("quickMenuB", "Quick Menu B");
    itemB.description = "Description of Quick Menu B";
    itemB.groupName = "Quick Menu";
    // No group name will be assigned to Quick Menu C and Quick Menu D, to put in Tasks group.
    var itemC = JumpListItem.createWithArguments("quickMenuC", "Quick Menu C");
    itemC.description = "Description of Quick Menu C";
    var itemD = JumpListItem.createWithArguments("quickMenuD", "Quick Menu D");
    itemD.description = "Description of Quick Menu D";
    // Add new 4 items in loadedJumpList.
    loadedJumpList.items.append(itemA);
    loadedJumpList.items.append(itemB);
    loadedJumpList.items.append(itemC);
    loadedJumpList.items.append(itemD);

}).done();
Running the code above from empty jump list should look like this.

Running the code above from empty jump list should look like this.

You can add separator too. Make a new separator by assigning Windows.UI.StartScreen.JumpListItem.createSeparator function's returned value to new variable. Then add it to list just like adding a shortcut menu. This separator will be inside the group.

JavaScript
var JumpList = Windows.UI.StartScreen.JumpList,
    JumpListItem = Windows.UI.StartScreen.JumpListItem;
// Load current jump list.
JumpList.loadCurrentAsync().then(function (loadedJumpList) {
    // loadedJumpList is the loaded jump list.
    // Set system group display mode. We'll set to frequent mode here.
    loadedJumpList.systemGroupKind = Windows.UI.StartScreen.JumpListSystemGroupKind.frequent;
    // Assign group name 'Quick Menu' to Quick Menu A and Quick Menu B.
    var itemA = JumpListItem.createWithArguments("quickMenuA", "Quick Menu A");
    itemA.description = "Description of Quick Menu A";
    itemA.groupName = "Quick Menu";
    var itemB = JumpListItem.createWithArguments("quickMenuB", "Quick Menu B");
    itemB.description = "Description of Quick Menu B";
    itemB.groupName = "Quick Menu";
    // No group name will be assigned to Quick Menu C and Quick Menu D, to put in Tasks group.
    var itemC = JumpListItem.createWithArguments("quickMenuC", "Quick Menu C");
    itemC.description = "Description of Quick Menu C";
    var itemD = JumpListItem.createWithArguments("quickMenuD", "Quick Menu D");
    itemD.description = "Description of Quick Menu D";
    // Make a new separator.
    var itemSep1 = JumpListItem.createSeparator();
    // Add new 4 items in loadedJumpList.
    loadedJumpList.items.append(itemA);
    loadedJumpList.items.append(itemB);
    loadedJumpList.items.append(itemC);
    loadedJumpList.items.append(itemD);

}).done();
Adding separator between Quick Menu C and D

Adding separator between Quick Menu C and D

 

Save jump list after modifying

We loaded the copy of jump list asynchronously, so we must save it when editing is done. Save it by executing Async function 'saveAsync'.

JavaScript
var JumpList = Windows.UI.StartScreen.JumpList,
    JumpListItem = Windows.UI.StartScreen.JumpListItem;
// Load current jump list.
JumpList.loadCurrentAsync().then(function (loadedJumpList) {
    // loadedJumpList is the loaded jump list.
    // Set system group display mode. We'll set to frequent mode here.
    loadedJumpList.systemGroupKind = Windows.UI.StartScreen.JumpListSystemGroupKind.frequent;
    // Assign group name 'Quick Menu' to Quick Menu A and Quick Menu B.
    var itemA = JumpListItem.createWithArguments("quickMenuA", "Quick Menu A");
    itemA.description = "Description of Quick Menu A";
    itemA.groupName = "Quick Menu";
    var itemB = JumpListItem.createWithArguments("quickMenuB", "Quick Menu B");
    itemB.description = "Description of Quick Menu B";
    itemB.groupName = "Quick Menu";
    // No group name will be assigned to Quick Menu C and Quick Menu D, to put in Tasks group.
    var itemC = JumpListItem.createWithArguments("quickMenuC", "Quick Menu C");
    itemC.description = "Description of Quick Menu C";
    var itemD = JumpListItem.createWithArguments("quickMenuD", "Quick Menu D");
    itemD.description = "Description of Quick Menu D";
    // Make a new separator.
    var itemSep1 = JumpListItem.createSeparator();
    // Add new 4 items in loadedJumpList.
    loadedJumpList.items.append(itemA);
    loadedJumpList.items.append(itemB);
    loadedJumpList.items.append(itemC);
    // Add separator between Item C and D.
    loadedJumpList.items.append(itemSep1);
    loadedJumpList.items.append(itemD);
    // When done, save list to take effect.
    return loadedJummpList.saveAsync();
}).done();
 

Removing selected items or everything in jump list

Asynchronously returned jump list from JumpList.loadCurrentAsync() is IList, which is similar with JavaScript's Array. If you want to empty the app's jump list, simply run items.clear(); (system group will not affected). You can also run items.splice(index, amount); to remove selected items.

JavaScript
var JumpList = Windows.UI.StartScreen.JumpList;
JumpList.loadCurrentAsync().then(function (loadedJumpList) {
    // Remove one item from second index.
    loadedJumpList.items.splice(1, 1);
    // Empty Jump List items in user group.
    // System group will not be affected.
    loadedJumpList.items.clear();
    // When done, save list to take effect.
    return loadedJumpList.saveAsync();
}).done();
 

Check if app was activated with jump list

UWP apps using web technology can define how app was activated by looking 'activationKind' which is inside at Windows.UI.WebUI.WebUIApplication.onactivated event (or WinJS.Application.onActivated event if using WinJS)'s second argument. Windows.ApplicationModel.Activation.ActivationKind describes how app was activated. When the app was activated by jump list's item, it'll look like when app has activated by simply clicking the icon. But, running with jump list's item will give argument that registered when the jump list item was programmatically added, so you just need to check 'arguments' inside first object of activatedEventArgs. Check the code below.

JavaScript
function activatedEvt (element, options) {
    var ActivationKind = Windows.ApplicationModel.Activation.ActivationKind;
    //
    if (options && options.activationKind === ActivationKind.launch &&
        options.activatedEventArgs.length > 0) {
        if (options.activatedEventArgs[0].arguments != "") {
            // App has been activated from jump list. Check 'argument' to find out which menu has been clicked.

        } else {
            // App has been activated by clicking the app icon (normal way).

        }
    } else {
        // App has been activated by other special way. Check 'ActivationKind' to know how.

    };
};

Windows.UI.WebUI.WebUIApplication.addEventListener("activated", activatedEvt);
////////// OR, IF YOU USE WINJS... //////////
WinJS.Application.addEventListener("activated", activatedEvt);