Bug 473045 - Win7 jump list platform support. r=robarnold, sr=roc.

This commit is contained in:
Jim Mathies 2009-10-06 16:42:45 -05:00
parent 84cb84a25b
commit d4f2c468aa
18 changed files with 2052 additions and 4 deletions

View File

@ -121,6 +121,9 @@ XPIDLSRCS += nsIPrintSettingsWin.idl \
nsITaskbarPreviewController.idl \
nsITaskbarPreviewButton.idl \
nsITaskbarProgress.idl \
nsITaskbarPreviewButton.idl \
nsIJumpListBuilder.idl \
nsIJumpListItem.idl \
$(NULL)
endif

View File

@ -0,0 +1,185 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jim Mathies <jmathies@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIArray;
interface nsIMutableArray;
[scriptable, uuid(1FE6A9CD-2B18-4dd5-A176-C2B32FA4F683)]
interface nsIJumpListBuilder : nsISupports
{
/**
* JumpLists
*
* Jump lists are built and then applied. Modifying an applied jump list is not
* permitted. Callers should begin the creation of a new jump list using
* initListBuild, add sub lists using addListBuild, then commit the jump list
* using commitListBuild. Lists are built in real-time during the sequence of
* build calls, make sure to check for errors on each individual step.
*
* The default number of allowed items in a jump list is ten. Users can change
* the number through system preferences. User may also pin items to jump lists,
* which take up additional slots. Applications do not have control over the
* number of items allowed in jump lists; excess items added are dropped by the
* system. Item insertion priority is defined as first to last added.
*
* Users may remove items from jump lists after they are commited. The system
* tracks removed items between commits. A list of these items is returned by
* a call to initListBuild. nsIJumpListBuilder does not filter entries added that
* have been removed since the last commit. To prevent repeatedly adding entires
* users have removed, applications are encoraged to track removed items
* internally.
*
* Each list is made up of an array of nsIWinJumpListItems representing items
* such as shortcuts, links, and separators. See nsIJumpListItem for information
* on adding additional jump list types.
*/
/**
* List Types
*/
/**
* Task List
*
* Tasks are common actions performed by users within the application. A task
* can be represented by an application shortcut and associated command line
* parameters or a URI. Task lists should generally be static lists that do not
* change often, if at all - similar to an application menu.
*
* Tasks are given the highest priority of all lists when space is limited.
*/
const short JUMPLIST_CATEGORY_TASKS = 0;
/**
* Recent or Frequent list
*
* Recent and frequent lists are based on Window's recent document lists. The
* lists are generated automatically by Windows. Applications that use recent
* or frequent lists should keep document use tracking up to date by calling
* the SHAddToRecentDocs shell api.
*/
const short JUMPLIST_CATEGORY_RECENT = 1;
const short JUMPLIST_CATEGORY_FREQUENT = 2;
/**
* Custom Lists
*
* Custom lists can be made up of tasks, links, and separators. The title of
* of the list is passed through the optional string parameter of addBuildList.
*/
const short JUMPLIST_CATEGORY_CUSTOMLIST = 3;
/**
* Indicates whether jump list taskbar features are supported by the current
* host.
*/
readonly attribute short available;
/**
* JumpList management
*
* @throw NS_ERROR_NOT_AVAILABLE on all calls if taskbar functionality
* is not supported by the operating system.
*/
/**
* Indicates if a commit has already occured in this session.
*/
readonly attribute boolean isListCommitted;
/**
* The maximum number of jump list items the current desktop can support.
*/
readonly attribute short maxListItems;
/**
* Initializes a jump list build and returns a list of items the user removed
* since the last time a jump list was committed. Removed items can become state
* after initListBuild is called, lists should be built in single-shot fasion.
*
* @param removedItems
* A list of items that were removed by the user since the last commit.
*
* @returns true if the operation completed successfully.
*/
boolean initListBuild(in nsIMutableArray removedItems);
/**
* Adds a list and if required, a set of items for the list.
*
* @param aCatType
* The type of list to add.
* @param items
* An array of nsIJumpListItem items to add to the list.
* @param catName
* For custom lists, the title of the list.
*
* @returns true if the operation completed successfully.
*
* @throw NS_ERROR_INVALID_ARG if incorrect parameters are passed for
* a particular category or item type.
* @throw NS_ERROR_ILLEGAL_VALUE if an item is added that was removed
* since the last commit.
* @throw NS_ERROR_UNEXPECTED on internal errors.
*/
boolean addListToBuild(in short aCatType, [optional] in nsIArray items, [optional] in AString catName);
/**
* Aborts and clears the current jump list build.
*/
void abortListBuild();
/**
* Commits the current jump list build to the Taskbar.
*
* @returns true if the operation completed successfully.
*/
boolean commitListBuild();
/**
* Deletes any currently applied taskbar jump list for this application.
* Common uses would be the enabling of a privacy mode and uninstallation.
*
* @returns true if the operation completed successfully.
*
* @throw NS_ERROR_UNEXPECTED on internal errors.
*/
boolean deleteActiveList();
};

View File

@ -0,0 +1,151 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jim Mathies <jmathies@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIURI;
interface nsILocalHandlerApp;
interface nsIMutableArray;
/**
* Implements Win7 Taskbar jump list item interfaces.
*
* Note to consumers: it's reasonable to expect we'll need support for other types
* of jump list items (an audio file, an email message, etc.). To add types,
* create the specific interface here, add an implementation class to WinJumpListItem,
* and add support to addListBuild & removed items processing.
*
*/
[scriptable, uuid(ACB8FB3C-E1B0-4044-8A50-E52C3E7C1057)]
interface nsIJumpListItem : nsISupports
{
const short JUMPLIST_ITEM_EMPTY = 0; // Empty list item
const short JUMPLIST_ITEM_SEPARATOR = 1; // Separator
const short JUMPLIST_ITEM_LINK = 2; // Web link item
const short JUMPLIST_ITEM_SHORTCUT = 3; // Application shortcut
/**
* Retrieves the jump list item type.
*/
readonly attribute short type;
/**
* Compare this item to another.
*
* Compares the type and other properties specific to this item's
* type.
*
* separator: type
* link: type, uri, title
* shortcut: type, handler app
*/
boolean equals(in nsIJumpListItem item);
};
/**
* A menu separator.
*/
[scriptable, uuid(69A2D5C5-14DC-47da-925D-869E0BD64D27)]
interface nsIJumpListSeparator : nsIJumpListItem
{
/* nothing needed here */
};
/**
* A URI link jump list item.
*
* Note the application must be the registered protocol
* handler for the protocol of the link.
*/
[scriptable, uuid(76EA47B1-C797-49b3-9F18-5E740A688524)]
interface nsIJumpListLink : nsIJumpListItem
{
/**
* Set or get the uri for this link item.
*/
attribute nsIURI uri;
/**
* Set or get the title for a link item.
*/
attribute AString uriTitle;
/**
* Get a 'privacy safe' unique string hash of the uri's
* spec. Useful in tracking removed items using visible
* data stores such as prefs. Generates an MD5 hash of
* the URI spec using nsICryptoHash.
*/
readonly attribute ACString uriHash;
/**
* Compare this item's hash to another uri.
*
* Generates a spec hash of the incoming uri and compares
* it to this item's uri spec hash.
*/
boolean compareHash(in nsIURI uri);
};
/**
* A generic application shortcut with command line support.
*/
[scriptable, uuid(9664389E-11D6-4bea-B68C-D70232162068)]
interface nsIJumpListShortcut : nsIJumpListItem
{
/**
* Set or get the handler app for this shortcut item.
*
* @throw NS_ERROR_FILE_NOT_FOUND if the handler app can
* not be found on the system.
*/
attribute nsILocalHandlerApp app;
/**
* Set or get the icon displayed with the jump list item.
*
* Indicates the resource index of the icon contained
* within the the handler executable.
*/
attribute long iconIndex;
};

View File

@ -47,6 +47,7 @@ interface nsITaskbarTabPreview;
interface nsITaskbarWindowPreview;
interface nsITaskbarPreviewController;
interface nsITaskbarProgress;
interface nsIJumpListBuilder;
/*
* nsIWinTaskbar
@ -75,8 +76,12 @@ interface nsITaskbarProgress;
* When taskbar icons are combined as is the default in Windows 7, the progress
* for those windows is also combined as defined here:
* http://msdn.microsoft.com/en-us/library/dd391697%28VS.85%29.aspx
*
* Applications may also define custom taskbar jump lists on application shortcuts
* users pin to the taskbar. See nsIJumpListBuilder for more information.
*/
[scriptable, uuid(0a3abac7-35b7-4b50-8381-7dbc3c55b061)]
[scriptable, uuid(4BC6D594-8FF0-4975-8642-3A5BC1928E81)]
interface nsIWinTaskbar : nsISupports
{
/**
@ -85,6 +90,10 @@ interface nsIWinTaskbar : nsISupports
*/
readonly attribute boolean available;
/**
* Taskbar window and tab preview management
*/
/**
* Creates a taskbar preview. The docshell is used to find the toplevel window.
* See the documentation for nsITaskbarTabPreview for more information.
@ -107,4 +116,16 @@ interface nsIWinTaskbar : nsISupports
* information.
*/
nsITaskbarProgress getTaskbarProgress(in nsIDocShell shell);
/**
* Retrieve a taskbar jump list builder
*
* Fails if a jump list build operation has already been initiated, developers
* should make use of a single instance of nsIJumpListBuilder for building lists
* within an application.
*
* @thow NS_ERROR_ALREADY_INITIALIZED if an nsIJumpListBuilder instance is
* currently building a list.
*/
nsIJumpListBuilder createJumpListBuilder();
};

View File

@ -137,6 +137,26 @@
#define NS_WIN_TASKBAR_CID \
{ 0xb8e5bc54, 0xa22f, 0x4eb2, {0xb0, 0x61, 0x24, 0xcb, 0x6d, 0x19, 0xc1, 0x5f } }
// {73A5946F-608D-454f-9D33-0B8F8C7294B6}
#define NS_WIN_JUMPLISTBUILDER_CID \
{ 0x73a5946f, 0x608d, 0x454f, { 0x9d, 0x33, 0xb, 0x8f, 0x8c, 0x72, 0x94, 0xb6 } }
// {2B9A1F2C-27CE-45b6-8D4E-755D0E34F8DB}
#define NS_WIN_JUMPLISTITEM_CID \
{ 0x2b9a1f2c, 0x27ce, 0x45b6, { 0x8d, 0x4e, 0x75, 0x5d, 0x0e, 0x34, 0xf8, 0xdb } }
// {21F1F13B-F75A-42ad-867A-D91AD694447E}
#define NS_WIN_JUMPLISTSEPARATOR_CID \
{ 0x21f1f13b, 0xf75a, 0x42ad, { 0x86, 0x7a, 0xd9, 0x1a, 0xd6, 0x94, 0x44, 0x7e } }
// {F72C5DC4-5A12-47be-BE28-AB105F33B08F}
#define NS_WIN_JUMPLISTLINK_CID \
{ 0xf72c5dc4, 0x5a12, 0x47be, { 0xbe, 0x28, 0xab, 0x10, 0x5f, 0x33, 0xb0, 0x8f } }
// {B16656B2-5187-498f-ABF4-56346126BFDB}
#define NS_WIN_JUMPLISTSHORTCUT_CID \
{ 0xb16656b2, 0x5187, 0x498f, { 0xab, 0xf4, 0x56, 0x34, 0x61, 0x26, 0xbf, 0xdb } }
//-----------------------------------------------------------
//Printing
//-----------------------------------------------------------

View File

@ -66,7 +66,7 @@ LOCAL_INCLUDES = \
OS_LIBS += $(call EXPAND_LIBNAME, uuid ole32 oleaut32 winspool)
ifneq ($(OS_ARCH), WINCE)
OS_LIBS += $(call EXPAND_LIBNAME, comctl32 comdlg32 shell32 imm32)
OS_LIBS += $(call EXPAND_LIBNAME, comctl32 comdlg32 shell32 imm32 shlwapi)
endif
SHARED_LIBRARY_LIBS = \

View File

@ -55,6 +55,8 @@
#include "nsToolkit.h"
#include "nsWindow.h"
#include "WinTaskbar.h"
#include "JumpListBuilder.h"
#include "JumpListItem.h"
// Drag & Drop, Clipboard
@ -93,6 +95,11 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
using namespace mozilla::widget;
NS_GENERIC_FACTORY_CONSTRUCTOR(WinTaskbar)
NS_GENERIC_FACTORY_CONSTRUCTOR(JumpListBuilder)
NS_GENERIC_FACTORY_CONSTRUCTOR(JumpListItem)
NS_GENERIC_FACTORY_CONSTRUCTOR(JumpListSeparator)
NS_GENERIC_FACTORY_CONSTRUCTOR(JumpListLink)
NS_GENERIC_FACTORY_CONSTRUCTOR(JumpListShortcut)
#endif
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
@ -175,6 +182,26 @@ static const nsModuleComponentInfo components[] =
NS_WIN_TASKBAR_CID ,
"@mozilla.org/windows-taskbar;1",
WinTaskbarConstructor },
{ "Windows JumpList Builder",
NS_WIN_JUMPLISTBUILDER_CID,
"@mozilla.org/windows-jumplistbuilder;1",
JumpListBuilderConstructor },
{ "Windows JumpList Item",
NS_WIN_JUMPLISTITEM_CID,
"@mozilla.org/windows-jumplistitem;1",
JumpListItemConstructor },
{ "Windows JumpList Separator",
NS_WIN_JUMPLISTSEPARATOR_CID,
"@mozilla.org/windows-jumplistseparator;1",
JumpListSeparatorConstructor },
{ "Windows JumpList Link",
NS_WIN_JUMPLISTLINK_CID,
"@mozilla.org/windows-jumplistlink;1",
JumpListLinkConstructor },
{ "Windows JumpList Shortcut",
NS_WIN_JUMPLISTSHORTCUT_CID,
"@mozilla.org/windows-jumplistshortcut;1",
JumpListShortcutConstructor },
#endif
{ "Drag Service",
NS_DRAGSERVICE_CID,

View File

@ -0,0 +1,412 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jim Mathies <jmathies@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
#include "JumpListBuilder.h"
#include "nsError.h"
#include "nsCOMPtr.h"
#include "nsServiceManagerUtils.h"
#include "nsAutoPtr.h"
#include "nsString.h"
#include "nsArrayUtils.h"
#include "nsIMutableArray.h"
#include "nsWidgetsCID.h"
namespace mozilla {
namespace widget {
static NS_DEFINE_CID(kJumpListItemCID, NS_WIN_JUMPLISTITEM_CID);
static NS_DEFINE_CID(kJumpListLinkCID, NS_WIN_JUMPLISTLINK_CID);
static NS_DEFINE_CID(kJumpListShortcutCID, NS_WIN_JUMPLISTSHORTCUT_CID);
// defined in WinTaskbar.cpp
extern const wchar_t *gMozillaJumpListIDGeneric;
PRPackedBool JumpListBuilder::sBuildingList = PR_FALSE;
NS_IMPL_ISUPPORTS1(JumpListBuilder, nsIJumpListBuilder)
JumpListBuilder::JumpListBuilder() :
mMaxItems(0),
mHasCommit(PR_FALSE)
{
::CoInitialize(NULL);
CoCreateInstance(CLSID_DestinationList, NULL, CLSCTX_INPROC_SERVER,
IID_ICustomDestinationList, getter_AddRefs(mJumpListMgr));
}
JumpListBuilder::~JumpListBuilder()
{
mJumpListMgr = nsnull;
::CoUninitialize();
}
/* readonly attribute short available; */
NS_IMETHODIMP JumpListBuilder::GetAvailable(PRInt16 *aAvailable)
{
*aAvailable = PR_FALSE;
if (mJumpListMgr)
*aAvailable = PR_TRUE;
return NS_OK;
}
/* readonly attribute boolean isListCommitted; */
NS_IMETHODIMP JumpListBuilder::GetIsListCommitted(PRBool *aCommit)
{
*aCommit = mHasCommit;
return NS_OK;
}
/* readonly attribute short maxItems; */
NS_IMETHODIMP JumpListBuilder::GetMaxListItems(PRInt16 *aMaxItems)
{
if (!mJumpListMgr)
return NS_ERROR_NOT_AVAILABLE;
*aMaxItems = 0;
if (sBuildingList) {
*aMaxItems = mMaxItems;
return NS_OK;
}
IObjectArray *objArray;
if (SUCCEEDED(mJumpListMgr->BeginList(&mMaxItems, IID_PPV_ARGS(&objArray)))) {
*aMaxItems = mMaxItems;
if (objArray)
objArray->Release();
mJumpListMgr->AbortList();
}
return NS_OK;
}
/* boolean initListBuild(in nsIMutableArray removedItems); */
NS_IMETHODIMP JumpListBuilder::InitListBuild(nsIMutableArray *removedItems, PRBool *_retval)
{
NS_ENSURE_ARG_POINTER(removedItems);
*_retval = PR_FALSE;
if (!mJumpListMgr)
return NS_ERROR_NOT_AVAILABLE;
if(sBuildingList)
AbortListBuild();
IObjectArray *objArray;
if (SUCCEEDED(mJumpListMgr->BeginList(&mMaxItems, IID_PPV_ARGS(&objArray)))) {
if (objArray) {
TransferIObjectArrayToIMutableArray(objArray, removedItems);
objArray->Release();
}
sBuildingList = PR_TRUE;
*_retval = PR_TRUE;
return NS_OK;
}
return NS_OK;
}
/* boolean addListToBuild(in short aCatType, [optional] in nsIArray items, [optional] in AString catName); */
NS_IMETHODIMP JumpListBuilder::AddListToBuild(PRInt16 aCatType, nsIArray *items, const nsAString &catName, PRBool *_retval)
{
nsresult rv;
*_retval = PR_FALSE;
if (!mJumpListMgr)
return NS_ERROR_NOT_AVAILABLE;
switch(aCatType) {
case nsIJumpListBuilder::JUMPLIST_CATEGORY_TASKS:
{
NS_ENSURE_ARG_POINTER(items);
HRESULT hr;
nsRefPtr<IObjectCollection> collection;
hr = CoCreateInstance(CLSID_EnumerableObjectCollection, NULL, CLSCTX_INPROC_SERVER,
IID_IObjectCollection, getter_AddRefs(collection));
if (FAILED(hr))
return NS_ERROR_UNEXPECTED;
// Build the list
PRUint32 length;
items->GetLength(&length);
for (PRUint32 i = 0; i < length; ++i) {
nsCOMPtr<nsIJumpListItem> item = do_QueryElementAt(items, i);
if (!item)
continue;
// Check for separators
if (IsSeparator(item)) {
nsRefPtr<IShellLinkW> link;
rv = JumpListSeparator::GetSeparator(link);
if (NS_FAILED(rv))
return rv;
collection->AddObject(link);
continue;
}
// These should all be ShellLinks
nsRefPtr<IShellLinkW> link;
rv = JumpListShortcut::GetShellLink(item, link);
if (NS_FAILED(rv))
return rv;
collection->AddObject(link);
}
// We need IObjectArray to submit
nsRefPtr<IObjectArray> pArray;
hr = collection->QueryInterface(IID_IObjectArray, getter_AddRefs(pArray));
if (FAILED(hr))
return NS_ERROR_UNEXPECTED;
// Add the tasks
hr = mJumpListMgr->AddUserTasks(pArray);
if (SUCCEEDED(hr))
*_retval = PR_TRUE;
return NS_OK;
}
break;
case nsIJumpListBuilder::JUMPLIST_CATEGORY_RECENT:
{
if (SUCCEEDED(mJumpListMgr->AppendKnownCategory(KDC_RECENT)))
*_retval = PR_TRUE;
return NS_OK;
}
break;
case nsIJumpListBuilder::JUMPLIST_CATEGORY_FREQUENT:
{
if (SUCCEEDED(mJumpListMgr->AppendKnownCategory(KDC_FREQUENT)))
*_retval = PR_TRUE;
return NS_OK;
}
break;
case nsIJumpListBuilder::JUMPLIST_CATEGORY_CUSTOMLIST:
{
NS_ENSURE_ARG_POINTER(items);
if (catName.IsEmpty())
return NS_ERROR_INVALID_ARG;
HRESULT hr;
nsRefPtr<IObjectCollection> collection;
hr = CoCreateInstance(CLSID_EnumerableObjectCollection, NULL, CLSCTX_INPROC_SERVER,
IID_IObjectCollection, getter_AddRefs(collection));
if (FAILED(hr))
return NS_ERROR_UNEXPECTED;
PRUint32 length;
items->GetLength(&length);
for (PRUint32 i = 0; i < length; ++i) {
nsCOMPtr<nsIJumpListItem> item = do_QueryElementAt(items, i);
if (!item)
continue;
PRInt16 type;
if (NS_FAILED(item->GetType(&type)))
continue;
switch(type) {
case nsIJumpListItem::JUMPLIST_ITEM_SEPARATOR:
{
nsRefPtr<IShellLinkW> shellItem;
rv = JumpListSeparator::GetSeparator(shellItem);
if (NS_FAILED(rv))
return rv;
collection->AddObject(shellItem);
}
break;
case nsIJumpListItem::JUMPLIST_ITEM_LINK:
{
nsRefPtr<IShellItem2> shellItem;
rv = JumpListLink::GetShellItem(item, shellItem);
if (NS_FAILED(rv))
return rv;
collection->AddObject(shellItem);
}
break;
case nsIJumpListItem::JUMPLIST_ITEM_SHORTCUT:
{
nsRefPtr<IShellLinkW> shellItem;
rv = JumpListShortcut::GetShellLink(item, shellItem);
if (NS_FAILED(rv))
return rv;
collection->AddObject(shellItem);
}
break;
}
}
// We need IObjectArray to submit
nsRefPtr<IObjectArray> pArray;
hr = collection->QueryInterface(IID_IObjectArray, (LPVOID*)&pArray);
if (FAILED(hr))
return NS_ERROR_UNEXPECTED;
// Add the tasks
hr = mJumpListMgr->AppendCategory(catName.BeginReading(), pArray);
if (SUCCEEDED(hr))
*_retval = PR_TRUE;
return NS_OK;
}
break;
}
return NS_OK;
}
/* void abortListBuild(); */
NS_IMETHODIMP JumpListBuilder::AbortListBuild()
{
if (!mJumpListMgr)
return NS_ERROR_NOT_AVAILABLE;
mJumpListMgr->AbortList();
sBuildingList = PR_FALSE;
return NS_OK;
}
/* boolean commitListBuild(); */
NS_IMETHODIMP JumpListBuilder::CommitListBuild(PRBool *_retval)
{
*_retval = PR_FALSE;
if (!mJumpListMgr)
return NS_ERROR_NOT_AVAILABLE;
HRESULT hr = mJumpListMgr->CommitList();
sBuildingList = PR_FALSE;
// XXX We might want some specific error data here.
if (SUCCEEDED(hr)) {
*_retval = PR_TRUE;
mHasCommit = PR_TRUE;
}
return NS_OK;
}
/* boolean deleteActiveList(); */
NS_IMETHODIMP JumpListBuilder::DeleteActiveList(PRBool *_retval)
{
*_retval = PR_FALSE;
if (!mJumpListMgr)
return NS_ERROR_NOT_AVAILABLE;
if(sBuildingList)
AbortListBuild();
if (SUCCEEDED(mJumpListMgr->DeleteList(gMozillaJumpListIDGeneric)))
*_retval = PR_TRUE;
return NS_OK;
}
/* internal */
PRBool JumpListBuilder::IsSeparator(nsCOMPtr<nsIJumpListItem>& item)
{
PRInt16 type;
item->GetType(&type);
if (NS_FAILED(item->GetType(&type)))
return PR_FALSE;
if (type == nsIJumpListItem::JUMPLIST_ITEM_SEPARATOR)
return PR_TRUE;
return PR_FALSE;
}
// TransferIObjectArrayToIMutableArray - used in converting removed items
// to our objects.
nsresult JumpListBuilder::TransferIObjectArrayToIMutableArray(IObjectArray *objArray, nsIMutableArray *removedItems)
{
NS_ENSURE_ARG_POINTER(objArray);
NS_ENSURE_ARG_POINTER(removedItems);
nsresult rv;
PRUint32 count = 0;
objArray->GetCount(&count);
nsCOMPtr<nsIJumpListItem> item;
for (PRUint32 idx = 0; idx < count; idx++) {
IShellLinkW * pLink = nsnull;
IShellItem * pItem = nsnull;
if (SUCCEEDED(objArray->GetAt(idx, IID_IShellLinkW, (LPVOID*)&pLink))) {
nsCOMPtr<nsIJumpListShortcut> shortcut =
do_CreateInstance(kJumpListShortcutCID, &rv);
if (NS_FAILED(rv))
return NS_ERROR_UNEXPECTED;
rv = JumpListShortcut::GetJumpListShortcut(pLink, shortcut);
item = do_QueryInterface(shortcut);
}
else if (SUCCEEDED(objArray->GetAt(idx, IID_IShellItem, (LPVOID*)&pItem))) {
nsCOMPtr<nsIJumpListLink> link =
do_CreateInstance(kJumpListLinkCID, &rv);
if (NS_FAILED(rv))
return NS_ERROR_UNEXPECTED;
rv = JumpListLink::GetJumpListLink(pItem, link);
item = do_QueryInterface(link);
}
if (pLink)
pLink->Release();
if (pItem)
pItem->Release();
if (NS_SUCCEEDED(rv)) {
removedItems->AppendElement(item, PR_FALSE);
}
}
return NS_OK;
}
} // namespace widget
} // namespace mozilla
#endif // MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7

View File

@ -0,0 +1,90 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jim Mathies <jmathies@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __JumpListBuilder_h__
#define __JumpListBuilder_h__
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
#include <windows.h>
#undef NTDDI_VERSION
#define NTDDI_VERSION NTDDI_WIN7
// Needed for various com interfaces
#include <shobjidl.h>
#include "nsString.h"
#include "nsIMutableArray.h"
#include "nsIJumpListBuilder.h"
#include "nsIJumpListItem.h"
#include "JumpListItem.h"
namespace mozilla {
namespace widget {
class JumpListBuilder : public nsIJumpListBuilder
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIJUMPLISTBUILDER
JumpListBuilder();
virtual ~JumpListBuilder();
protected:
static PRPackedBool sBuildingList;
private:
nsRefPtr<ICustomDestinationList> mJumpListMgr;
PRUint32 mMaxItems;
PRBool mHasCommit;
PRBool IsSeparator(nsCOMPtr<nsIJumpListItem>& item);
nsresult TransferIObjectArrayToIMutableArray(IObjectArray *objArray, nsIMutableArray *removedItems);
friend class WinTaskbar;
};
} // namespace widget
} // namespace mozilla
#endif // MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
#endif /* __JumpListBuilder_h__ */

View File

@ -0,0 +1,620 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jim Mathies <jmathies@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
#include "JumpListItem.h"
#include <shellapi.h>
#include <propvarutil.h>
#include <propkey.h>
#include "nsIFile.h"
#include "nsILocalFile.h"
#include "nsNetUtil.h"
#include "nsCRT.h"
#include "nsNetCID.h"
#include "nsCExternalHandlerService.h"
namespace mozilla {
namespace widget {
// SHCreateItemFromParsingName is only available on vista and up. We only load this if we
// need to call it on win7+.
JumpListLink::SHCreateItemFromParsingNamePtr JumpListLink::createItemFromParsingName = nsnull;
const PRUnichar JumpListLink::kSehllLibraryName[] = L"shell32.dll";
HMODULE JumpListLink::sShellDll = nsnull;
// ISUPPORTS Impl's
NS_IMPL_ISUPPORTS1(JumpListItem,
nsIJumpListItem)
NS_IMPL_ISUPPORTS_INHERITED1(JumpListSeparator,
JumpListItem,
nsIJumpListSeparator)
NS_IMPL_ISUPPORTS_INHERITED1(JumpListLink,
JumpListItem,
nsIJumpListLink)
NS_IMPL_ISUPPORTS_INHERITED1(JumpListShortcut,
JumpListItem,
nsIJumpListShortcut)
/* attribute short type; */
NS_IMETHODIMP JumpListItem::GetType(PRInt16 *aType)
{
NS_ENSURE_ARG_POINTER(aType);
*aType = mItemType;
return NS_OK;
}
/* boolean equals(nsIJumpListItem item); */
NS_IMETHODIMP JumpListItem::Equals(nsIJumpListItem *aItem, PRBool *aResult)
{
NS_ENSURE_ARG_POINTER(aItem);
*aResult = PR_FALSE;
PRInt16 theType = nsIJumpListItem::JUMPLIST_ITEM_EMPTY;
if (NS_FAILED(aItem->GetType(&theType)))
return NS_OK;
// Make sure the types match.
if (Type() != theType)
return NS_OK;
*aResult = PR_TRUE;
return NS_OK;
}
/* link impl. */
/* attribute nsIURI uri; */
NS_IMETHODIMP JumpListLink::GetUri(nsIURI **aURI)
{
NS_IF_ADDREF(*aURI = mURI);
return NS_OK;
}
NS_IMETHODIMP JumpListLink::SetUri(nsIURI *aURI)
{
mURI = aURI;
return NS_OK;
}
/* attribute AString uriTitle; */
NS_IMETHODIMP JumpListLink::SetUriTitle(const nsAString &aUriTitle)
{
mUriTitle.Assign(aUriTitle);
return NS_OK;
}
NS_IMETHODIMP JumpListLink::GetUriTitle(nsAString& aUriTitle)
{
aUriTitle.Assign(mUriTitle);
return NS_OK;
}
/* readonly attribute long uriHash; */
NS_IMETHODIMP JumpListLink::GetUriHash(nsACString& aUriHash)
{
if (!mURI)
return NS_ERROR_NOT_AVAILABLE;
return HashURI(mURI, aUriHash);
}
/* boolean compareHash(in nsIURI uri); */
NS_IMETHODIMP JumpListLink::CompareHash(nsIURI *aUri, PRBool *aResult)
{
nsresult rv;
if (!mURI) {
*aResult = !aUri;
return NS_OK;
}
NS_ENSURE_ARG_POINTER(aUri);
nsCAutoString hash1, hash2;
rv = HashURI(mURI, hash1);
NS_ENSURE_SUCCESS(rv, rv);
rv = HashURI(aUri, hash2);
NS_ENSURE_SUCCESS(rv, rv);
*aResult = hash1.Equals(hash2);
return NS_OK;
}
/* boolean equals(nsIJumpListItem item); */
NS_IMETHODIMP JumpListLink::Equals(nsIJumpListItem *aItem, PRBool *aResult)
{
NS_ENSURE_ARG_POINTER(aItem);
nsresult rv;
*aResult = PR_FALSE;
PRInt16 theType = nsIJumpListItem::JUMPLIST_ITEM_EMPTY;
if (NS_FAILED(aItem->GetType(&theType)))
return NS_OK;
// Make sure the types match.
if (Type() != theType)
return NS_OK;
nsCOMPtr<nsIJumpListLink> link = do_QueryInterface(aItem, &rv);
if (NS_FAILED(rv))
return rv;
// Check the titles
nsAutoString title;
link->GetUriTitle(title);
if (!mUriTitle.Equals(title))
return NS_OK;
// Call the internal object's equals() method to check.
nsCOMPtr<nsIURI> theUri;
PRBool equals = PR_FALSE;
if (NS_SUCCEEDED(link->GetUri(getter_AddRefs(theUri)))) {
if (!theUri) {
if (!mURI)
*aResult = PR_TRUE;
return NS_OK;
}
if (NS_SUCCEEDED(theUri->Equals(mURI, &equals)) && equals) {
*aResult = PR_TRUE;
}
}
return NS_OK;
}
/* shortcut impl. */
/* attribute nsILocalHandlerApp app; */
NS_IMETHODIMP JumpListShortcut::GetApp(nsILocalHandlerApp **aApp)
{
NS_IF_ADDREF(*aApp = mHandlerApp);
return NS_OK;
}
NS_IMETHODIMP JumpListShortcut::SetApp(nsILocalHandlerApp *aApp)
{
mHandlerApp = aApp;
// Confirm the app is present on the system
if (!ExecutableExists(mHandlerApp))
return NS_ERROR_FILE_NOT_FOUND;
return NS_OK;
}
/* attribute long iconIndex; */
NS_IMETHODIMP JumpListShortcut::GetIconIndex(PRInt32 *aIconIndex)
{
NS_ENSURE_ARG_POINTER(aIconIndex);
*aIconIndex = mIconIndex;
return NS_OK;
}
NS_IMETHODIMP JumpListShortcut::SetIconIndex(PRInt32 aIconIndex)
{
mIconIndex = aIconIndex;
return NS_OK;
}
/* boolean equals(nsIJumpListItem item); */
NS_IMETHODIMP JumpListShortcut::Equals(nsIJumpListItem *aItem, PRBool *aResult)
{
NS_ENSURE_ARG_POINTER(aItem);
nsresult rv;
*aResult = PR_FALSE;
PRInt16 theType = nsIJumpListItem::JUMPLIST_ITEM_EMPTY;
if (NS_FAILED(aItem->GetType(&theType)))
return NS_OK;
// Make sure the types match.
if (Type() != theType)
return NS_OK;
nsCOMPtr<nsIJumpListShortcut> shortcut = do_QueryInterface(aItem, &rv);
if (NS_FAILED(rv))
return rv;
// Check the icon index
//PRInt32 idx;
//shortcut->GetIconIndex(&idx);
//if (mIconIndex != idx)
// return NS_OK;
// Call the internal object's equals() method to check.
nsCOMPtr<nsILocalHandlerApp> theApp;
PRBool equals = PR_FALSE;
if (NS_SUCCEEDED(shortcut->GetApp(getter_AddRefs(theApp)))) {
if (!theApp) {
if (!mHandlerApp)
*aResult = PR_TRUE;
return NS_OK;
}
if (NS_SUCCEEDED(theApp->Equals(mHandlerApp, &equals)) && equals) {
*aResult = PR_TRUE;
}
}
return NS_OK;
}
/* internal helpers */
// (static) Creates a ShellLink that encapsulate a separator.
nsresult JumpListSeparator::GetSeparator(nsRefPtr<IShellLinkW>& aShellLink)
{
HRESULT hr;
IShellLinkW* psl;
// Create a IShellLink.
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLinkW, (LPVOID*)&psl);
if (FAILED(hr))
return NS_ERROR_UNEXPECTED;
IPropertyStore* pPropStore = nsnull;
hr = psl->QueryInterface(IID_IPropertyStore, (LPVOID*)&pPropStore);
if (FAILED(hr))
return NS_ERROR_UNEXPECTED;
PROPVARIANT pv;
InitPropVariantFromBoolean(TRUE, &pv);
pPropStore->SetValue(PKEY_AppUserModel_IsDestListSeparator, pv);
pPropStore->Commit();
pPropStore->Release();
PropVariantClear(&pv);
aShellLink = dont_AddRef(psl);
return NS_OK;
}
// (static) Creates a ShellLink that encapsulate a shortcut to local apps.
nsresult JumpListShortcut::GetShellLink(nsCOMPtr<nsIJumpListItem>& item, nsRefPtr<IShellLinkW>& aShellLink)
{
HRESULT hr;
IShellLinkW* psl;
nsresult rv;
// Shell links:
// http://msdn.microsoft.com/en-us/library/bb776891(VS.85).aspx
// http://msdn.microsoft.com/en-us/library/bb774950(VS.85).aspx
PRInt16 type;
if (NS_FAILED(item->GetType(&type)))
return NS_ERROR_INVALID_ARG;
if (type != nsIJumpListItem::JUMPLIST_ITEM_SHORTCUT)
return NS_ERROR_INVALID_ARG;
nsCOMPtr<nsIJumpListShortcut> shortcut = do_QueryInterface(item, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILocalHandlerApp> handlerApp;
rv = shortcut->GetApp(getter_AddRefs(handlerApp));
NS_ENSURE_SUCCESS(rv, rv);
// Create a IShellLink
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLinkW, (LPVOID*)&psl);
if (FAILED(hr))
return NS_ERROR_UNEXPECTED;
// Retrieve the app path, title, description and optional command line args.
nsAutoString appPath, appTitle, appDescription, appArgs;
PRInt32 appIconIndex = 0;
// Path
nsCOMPtr<nsIFile> executable;
handlerApp->GetExecutable(getter_AddRefs(executable));
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(executable, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = localFile->GetPath(appPath);
NS_ENSURE_SUCCESS(rv, rv);
// Command line parameters
PRUint32 count = 0;
handlerApp->GetParameterCount(&count);
for (PRUint32 idx = 0; idx < count; idx++) {
if (idx > 0)
appArgs.Append(NS_LITERAL_STRING(" "));
nsAutoString param;
rv = handlerApp->GetParameter(idx, param);
if (NS_FAILED(rv))
return rv;
appArgs.Append(param);
}
handlerApp->GetName(appTitle);
handlerApp->GetDetailedDescription(appDescription);
shortcut->GetIconIndex(&appIconIndex);
// Store the title of the app
if (appTitle.Length() > 0) {
IPropertyStore* pPropStore = nsnull;
hr = psl->QueryInterface(IID_IPropertyStore, (LPVOID*)&pPropStore);
if (FAILED(hr))
return NS_ERROR_UNEXPECTED;
PROPVARIANT pv;
InitPropVariantFromString(appTitle.get(), &pv);
pPropStore->SetValue(PKEY_Title, pv);
pPropStore->Commit();
pPropStore->Release();
PropVariantClear(&pv);
}
// Store the rest of the params
psl->SetPath(appPath.get());
psl->SetDescription(appDescription.get());
psl->SetArguments(appArgs.get());
psl->SetIconLocation(appPath.get(), appIconIndex);
aShellLink = dont_AddRef(psl);
return NS_OK;
}
// (static) For a given IShellLink, create and return a populated nsIJumpListShortcut.
nsresult JumpListShortcut::GetJumpListShortcut(IShellLinkW *pLink, nsCOMPtr<nsIJumpListShortcut>& aShortcut)
{
NS_ENSURE_ARG_POINTER(pLink);
nsresult rv;
HRESULT hres;
nsCOMPtr<nsILocalHandlerApp> handlerApp =
do_CreateInstance(NS_LOCALHANDLERAPP_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRUnichar buf[MAX_PATH];
// Path
hres = pLink->GetPath((LPWSTR)&buf, MAX_PATH, NULL, SLGP_UNCPRIORITY);
if (FAILED(hres))
return NS_ERROR_INVALID_ARG;
nsCOMPtr<nsILocalFile> file;
nsDependentString filepath(buf);
rv = NS_NewLocalFile(filepath, PR_FALSE, getter_AddRefs(file));
NS_ENSURE_SUCCESS(rv, rv);
rv = handlerApp->SetExecutable(file);
NS_ENSURE_SUCCESS(rv, rv);
// Parameters
hres = pLink->GetArguments((LPWSTR)&buf, MAX_PATH);
if (SUCCEEDED(hres)) {
LPWSTR *arglist;
PRInt32 numArgs;
PRInt32 idx;
arglist = ::CommandLineToArgvW(buf, &numArgs);
if(arglist) {
for (idx = 0; idx < numArgs; idx++) {
// szArglist[i] is null terminated
nsDependentString arg(arglist[idx]);
handlerApp->AppendParameter(arg);
}
::LocalFree(arglist);
}
}
rv = aShortcut->SetApp(handlerApp);
NS_ENSURE_SUCCESS(rv, rv);
// Icon index or file location
int iconIdx = 0;
hres = pLink->GetIconLocation((LPWSTR)&buf, MAX_PATH, &iconIdx);
if (SUCCEEDED(hres)) {
// XXX How do we handle converting local files to images here? Do we need to?
aShortcut->SetIconIndex(iconIdx);
}
// Do we need the title and description? Probably not since handler app doesn't compare
// these in equals.
return NS_OK;
}
// (static) ShellItems are used to encapsulate links to things. We currently only support URI links,
// but more support could be added, such as local file and directory links.
nsresult JumpListLink::GetShellItem(nsCOMPtr<nsIJumpListItem>& item, nsRefPtr<IShellItem2>& aShellItem)
{
IShellItem2 *psi = nsnull;
nsresult rv;
PRInt16 type;
if (NS_FAILED(item->GetType(&type)))
return NS_ERROR_INVALID_ARG;
if (type != nsIJumpListItem::JUMPLIST_ITEM_LINK)
return NS_ERROR_INVALID_ARG;
nsCOMPtr<nsIJumpListLink> link = do_QueryInterface(item, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> uri;
rv = link->GetUri(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString spec;
rv = uri->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
// Load vista+ SHCreateItemFromParsingName
if (createItemFromParsingName == nsnull) {
if (sShellDll)
return NS_ERROR_UNEXPECTED;
sShellDll = ::LoadLibraryW(kSehllLibraryName);
if (sShellDll)
createItemFromParsingName = (SHCreateItemFromParsingNamePtr)GetProcAddress(sShellDll, "SHCreateItemFromParsingName");
if (createItemFromParsingName == nsnull)
return NS_ERROR_UNEXPECTED;
}
// Create the IShellItem
if (FAILED(createItemFromParsingName(NS_ConvertASCIItoUTF16(spec).get(),
NULL, IID_PPV_ARGS(&psi))))
return NS_ERROR_INVALID_ARG;
// Set the title
nsAutoString linkTitle;
link->GetUriTitle(linkTitle);
IPropertyStore* pPropStore = nsnull;
HRESULT hres = psi->GetPropertyStore(GPS_DEFAULT, IID_IPropertyStore, (void**)&pPropStore);
if (FAILED(hres))
return NS_ERROR_UNEXPECTED;
PROPVARIANT pv;
InitPropVariantFromString(linkTitle.get(), &pv);
// May fail due to shell item access permissions.
pPropStore->SetValue(PKEY_ItemName, pv);
pPropStore->Commit();
pPropStore->Release();
PropVariantClear(&pv);
aShellItem = dont_AddRef(psi);
return NS_OK;
}
// (static) For a given IShellItem, create and return a populated nsIJumpListLink.
nsresult JumpListLink::GetJumpListLink(IShellItem *pItem, nsCOMPtr<nsIJumpListLink>& aLink)
{
NS_ENSURE_ARG_POINTER(pItem);
// We assume for now these are URI links, but through properties we could
// query and create other types.
nsresult rv;
LPWSTR lpstrName = NULL;
if (SUCCEEDED(pItem->GetDisplayName(SIGDN_URL, &lpstrName))) {
nsCOMPtr<nsIURI> uri;
nsAutoString spec(lpstrName);
rv = NS_NewURI(getter_AddRefs(uri), NS_ConvertUTF16toUTF8(spec));
if (NS_FAILED(rv))
return NS_ERROR_INVALID_ARG;
aLink->SetUri(uri);
::CoTaskMemFree(lpstrName);
}
return NS_OK;
}
// Confirm the app is on the system
PRBool JumpListShortcut::ExecutableExists(nsCOMPtr<nsILocalHandlerApp>& handlerApp)
{
nsresult rv;
if (!handlerApp)
return PR_FALSE;
nsCOMPtr<nsIFile> executable;
rv = handlerApp->GetExecutable(getter_AddRefs(executable));
if (NS_SUCCEEDED(rv) && executable) {
PRBool exists;
executable->Exists(&exists);
return exists;
}
return PR_FALSE;
}
nsresult JumpListLink::HashURI(nsIURI *aUri, nsACString& aUriHash)
{
nsresult rv;
if (!aUri)
return NS_ERROR_INVALID_ARG;
nsCAutoString spec;
rv = aUri->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
if (!mCryptoHash) {
mCryptoHash = do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = mCryptoHash->Init(nsICryptoHash::MD5);
NS_ENSURE_SUCCESS(rv, rv);
rv = mCryptoHash->Update(reinterpret_cast<const PRUint8*>(spec.BeginReading()), spec.Length());
NS_ENSURE_SUCCESS(rv, rv);
rv = mCryptoHash->Finish(PR_TRUE, aUriHash);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
} // namespace widget
} // namespace mozilla
#endif // MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7

View File

@ -0,0 +1,148 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jim Mathies <jmathies@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __JumpListItem_h__
#define __JumpListItem_h__
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
#include <windows.h>
#include <shobjidl.h>
#include "nsIJumpListItem.h" // defines nsIJumpListItem
#include "nsIMIMEInfo.h" // defines nsILocalHandlerApp
#include "nsTArray.h"
#include "nsIMutableArray.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsIURI.h"
#include "nsICryptoHash.h"
#include "nsString.h"
namespace mozilla {
namespace widget {
class JumpListItem : public nsIJumpListItem
{
public:
JumpListItem() :
mItemType(nsIJumpListItem::JUMPLIST_ITEM_EMPTY)
{}
JumpListItem(PRInt32 type) :
mItemType(type)
{}
NS_DECL_ISUPPORTS
NS_DECL_NSIJUMPLISTITEM
protected:
short Type() { return mItemType; }
short mItemType;
};
class JumpListSeparator : public JumpListItem, public nsIJumpListSeparator
{
public:
JumpListSeparator() :
JumpListItem(nsIJumpListItem::JUMPLIST_ITEM_SEPARATOR)
{}
NS_DECL_ISUPPORTS_INHERITED
NS_IMETHOD GetType(PRInt16 *aType) { return JumpListItem::GetType(aType); }
NS_IMETHOD Equals(nsIJumpListItem *item, PRBool *_retval) { return JumpListItem::Equals(item, _retval); }
static nsresult GetSeparator(nsRefPtr<IShellLinkW>& aShellLink);
};
class JumpListLink : public JumpListItem, public nsIJumpListLink
{
public:
JumpListLink() :
JumpListItem(nsIJumpListItem::JUMPLIST_ITEM_LINK)
{}
NS_DECL_ISUPPORTS_INHERITED
NS_IMETHOD GetType(PRInt16 *aType) { return JumpListItem::GetType(aType); }
NS_IMETHOD Equals(nsIJumpListItem *item, PRBool *_retval);
NS_DECL_NSIJUMPLISTLINK
static nsresult GetShellItem(nsCOMPtr<nsIJumpListItem>& item, nsRefPtr<IShellItem2>& aShellItem);
static nsresult GetJumpListLink(IShellItem *pItem, nsCOMPtr<nsIJumpListLink>& aLink);
protected:
typedef HRESULT (WINAPI * SHCreateItemFromParsingNamePtr)(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);
nsString mUriTitle;
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsICryptoHash> mCryptoHash;
static const PRUnichar kSehllLibraryName[];
static HMODULE sShellDll;
static SHCreateItemFromParsingNamePtr createItemFromParsingName;
nsresult HashURI(nsIURI *uri, nsACString& aUriHas);
};
class JumpListShortcut : public JumpListItem, public nsIJumpListShortcut
{
public:
JumpListShortcut() :
JumpListItem(nsIJumpListItem::JUMPLIST_ITEM_SHORTCUT)
{}
NS_DECL_ISUPPORTS_INHERITED
NS_IMETHOD GetType(PRInt16 *aType) { return JumpListItem::GetType(aType); }
NS_IMETHOD Equals(nsIJumpListItem *item, PRBool *_retval);
NS_DECL_NSIJUMPLISTSHORTCUT
static nsresult GetShellLink(nsCOMPtr<nsIJumpListItem>& item, nsRefPtr<IShellLinkW>& aShellLink);
static nsresult GetJumpListShortcut(IShellLinkW *pLink, nsCOMPtr<nsIJumpListShortcut>& aShortcut);
protected:
PRInt32 mIconIndex;
nsCOMPtr<nsILocalHandlerApp> mHandlerApp;
PRBool ExecutableExists(nsCOMPtr<nsILocalHandlerApp>& handlerApp);
};
} // namespace widget
} // namespace mozilla
#endif // MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
#endif /* __JumpListItem_h__ */

View File

@ -70,6 +70,8 @@ CPPSRCS = \
TaskbarTabPreview.cpp \
TaskbarWindowPreview.cpp \
TaskbarPreviewButton.cpp \
JumpListBuilder.cpp \
JumpListItem.cpp \
$(NULL)
ifdef NS_PRINTING

View File

@ -23,6 +23,7 @@
*
* Contributor(s):
* Rob Arnold <tellrob@gmail.com>
* Jim Mathies <jmathies@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -51,12 +52,19 @@
#include <nsIObserverService.h>
#include <nsServiceManagerUtils.h>
#include <nsAutoPtr.h>
#include "nsIJumpListBuilder.h"
#include "nsUXThemeData.h"
#include "nsWindow.h"
#include "TaskbarTabPreview.h"
#include "TaskbarWindowPreview.h"
#include "JumpListBuilder.h"
#include "nsWidgetsCID.h"
#include <io.h>
const PRUnichar kShellLibraryName[] = L"shell32.dll";
static NS_DEFINE_CID(kJumpListBuilderCID, NS_WIN_JUMPLISTBUILDER_CID);
namespace {
HWND
GetHWNDFromDocShell(nsIDocShell *aShell) {
@ -151,6 +159,21 @@ NS_IMPL_ISUPPORTS1(DefaultController, nsITaskbarPreviewController);
namespace mozilla {
namespace widget {
// Unique identifier for a particular application. Windows uses this to group
// windows from the same process and to tie jump lists to processes. The ID
// should be unique per application version. If developers plan on using jump
// list links (nsIJumpListLink) this ID should also be associated with the
// prog id of the protocol handler of the links. To override the default below,
// define MOZ_TASKBAR_ID.
#ifndef MOZ_TASKBAR_ID
#define MOZ_COMPANY Mozilla
#define MOZTBID1(x) L#x
#define MOZTBID2(a,b,c) MOZTBID1(a##.##b##.##c)
#define MOZTBID(a,b,c) MOZTBID2(a,b,c)
#define MOZ_TASKBAR_ID MOZTBID(MOZ_COMPANY, MOZ_BUILD_APP, MOZILLA_VERSION_U)
#endif
const wchar_t *gMozillaJumpListIDGeneric = MOZ_TASKBAR_ID;
NS_IMPL_ISUPPORTS1(WinTaskbar, nsIWinTaskbar)
WinTaskbar::WinTaskbar()
@ -176,6 +199,30 @@ WinTaskbar::~WinTaskbar() {
::CoUninitialize();
}
// (static) Called from AppShell
PRBool WinTaskbar::SetAppUserModelID()
{
SetCurrentProcessExplicitAppUserModelIDPtr funcAppUserModelID = nsnull;
PRBool retVal = PR_FALSE;
// #define MOZ_TASKBAR_ID L""
if (*gMozillaJumpListIDGeneric == nsnull)
return PR_FALSE;
HMODULE hDLL = ::LoadLibraryW(kShellLibraryName);
funcAppUserModelID = (SetCurrentProcessExplicitAppUserModelIDPtr)
GetProcAddress(hDLL, "SetCurrentProcessExplicitAppUserModelID");
if (funcAppUserModelID && SUCCEEDED(funcAppUserModelID(gMozillaJumpListIDGeneric)))
retVal = PR_TRUE;
if (hDLL)
::FreeLibrary(hDLL);
return retVal;
}
NS_IMETHODIMP
WinTaskbar::GetAvailable(PRBool *aAvailable) {
*aAvailable = mTaskbar != nsnull;
@ -238,6 +285,24 @@ WinTaskbar::GetTaskbarProgress(nsIDocShell *shell, nsITaskbarProgress **_retval)
return CallQueryInterface(preview, _retval);
}
/* nsIJumpListBuilder createJumpListBuilder(); */
NS_IMETHODIMP WinTaskbar::CreateJumpListBuilder(nsIJumpListBuilder * *aJumpListBuilder)
{
nsresult rv;
if (JumpListBuilder::sBuildingList)
return NS_ERROR_ALREADY_INITIALIZED;
nsCOMPtr<nsIJumpListBuilder> builder =
do_CreateInstance(kJumpListBuilderCID, &rv);
if (NS_FAILED(rv))
return NS_ERROR_UNEXPECTED;
NS_IF_ADDREF(*aJumpListBuilder = builder);
return NS_OK;
}
} // namespace widget
} // namespace mozilla

View File

@ -58,7 +58,13 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIWINTASKBAR
// Registers the global app user model id for the instance. See comments in WinTaskbar.cpp
// for more information.
static PRBool SetAppUserModelID();
private:
typedef HRESULT (WINAPI * SetCurrentProcessExplicitAppUserModelIDPtr)(PCWSTR AppID);
ITaskbarList4 *mTaskbar;
};

View File

@ -40,6 +40,7 @@
#include "nsAppShell.h"
#include "nsToolkit.h"
#include "nsThreadUtils.h"
#include "WinTaskbar.h"
#ifdef WINCE
BOOL WaitMessage(VOID)
@ -123,6 +124,10 @@ nsAppShell::Init()
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
sTaskbarButtonCreatedMsg = ::RegisterWindowMessageW(L"TaskbarButtonCreated");
NS_ASSERTION(sTaskbarButtonCreatedMsg, "Could not register taskbar button creation message");
// Global app registration id for Win7 and up. See
// WinTaskbar.cpp for details.
mozilla::widget::WinTaskbar::SetAppUserModelID();
#endif
WNDCLASSW wc;

View File

@ -48,7 +48,7 @@
#include "nsPoint.h"
#include "nsGUIEvent.h"
#if !defined(NTDDI_WIN7) || NTDDI_VERSION < NTDDI_WIN7
#ifndef HGESTUREINFO // needs WINVER >= 0x0601
DECLARE_HANDLE(HGESTUREINFO);
@ -163,7 +163,7 @@ typedef struct tagGESTURENOTIFYSTRUCT {
// WM_TABLET_QUERYSYSTEMGESTURESTATUS return values
#define TABLET_ROTATE_GESTURE_ENABLE 0x02000000
#endif /* NTDDI_VERSION < NTDDI_WIN7 */
#endif /* #ifndef HGESTUREINFO */
class nsPointWin : public nsIntPoint
{

View File

@ -43,6 +43,9 @@ relativesrcdir = widget/tests
include $(DEPTH)/config/autoconf.mk
MODULE = test_widget
XPCSHELL_TESTS = unit
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
ifdef NS_ENABLE_TSF
CPP_UNIT_TESTS += TestWinTSF.cpp \

View File

@ -0,0 +1,290 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jim Mathies <jmathies@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// This tests taskbar jump list functionality available on win7 and up.
const Cc = Components.classes;
const Ci = Components.interfaces;
function test_basics()
{
var item = Cc["@mozilla.org/windows-jumplistitem;1"].
createInstance(Ci.nsIJumpListItem);
var sep = Cc["@mozilla.org/windows-jumplistseparator;1"].
createInstance(Ci.nsIJumpListSeparator);
var shortcut = Cc["@mozilla.org/windows-jumplistshortcut;1"].
createInstance(Ci.nsIJumpListShortcut);
var link = Cc["@mozilla.org/windows-jumplistlink;1"].
createInstance(Ci.nsIJumpListLink);
do_check_false(item.equals(sep));
do_check_false(item.equals(shortcut));
do_check_false(item.equals(link));
do_check_false(sep.equals(item));
do_check_false(sep.equals(shortcut));
do_check_false(sep.equals(link));
do_check_false(shortcut.equals(item));
do_check_false(shortcut.equals(sep));
do_check_false(shortcut.equals(link));
do_check_false(link.equals(item));
do_check_false(link.equals(sep));
do_check_false(link.equals(shortcut));
do_check_true(item.equals(item));
do_check_true(sep.equals(sep));
do_check_true(link.equals(link));
do_check_true(shortcut.equals(shortcut));
}
function test_separator()
{
// separators:
var item = Cc["@mozilla.org/windows-jumplistseparator;1"].
createInstance(Ci.nsIJumpListSeparator);
do_check_true(item.type == Ci.nsIJumpListItem.JUMPLIST_ITEM_SEPARATOR);
}
function test_hashes()
{
var link = Cc["@mozilla.org/windows-jumplistlink;1"]
.createInstance(Ci.nsIJumpListLink);
var uri1 = Cc["@mozilla.org/network/simple-uri;1"]
.createInstance(Ci.nsIURI);
var uri2 = Cc["@mozilla.org/network/simple-uri;1"]
.createInstance(Ci.nsIURI);
uri1.spec = "http://www.123.com/";
uri2.spec = "http://www.123.com/";
link.uri = uri1;
do_check_true(link.compareHash(uri2))
uri2.spec = "http://www.456.com/";
do_check_false(link.compareHash(uri2))
uri2.spec = "http://www.123.com/";
do_check_true(link.compareHash(uri2))
uri2.spec = "https://www.123.com/";
do_check_false(link.compareHash(uri2))
uri2.spec = "http://www.123.com/test/";
do_check_false(link.compareHash(uri2))
uri1.spec = "http://www.123.com/test/";
uri2.spec = "http://www.123.com/test/";
do_check_true(link.compareHash(uri2))
uri1.spec = "https://www.123.com/test/";
uri2.spec = "https://www.123.com/test/";
do_check_true(link.compareHash(uri2))
uri2.spec = "ftp://www.123.com/test/";
do_check_false(link.compareHash(uri2))
uri2.spec = "http://123.com/test/";
do_check_false(link.compareHash(uri2))
uri1.spec = "https://www.123.com/test/";
uri2.spec = "https://www.123.com/Test/";
do_check_false(link.compareHash(uri2))
uri1.spec = "http://www.123.com/";
do_check_eq(link.uriHash, "QGLmWuwuTozr3tOfXSf5mg==");
uri1.spec = "http://www.123.com/test/";
do_check_eq(link.uriHash, "AG87Ls+GmaUYSUJFETRr3Q==");
uri1.spec = "https://www.123.com/";
do_check_eq(link.uriHash, "iSx6UH1a9enVPzUA9JZ42g==");
var uri3 = Cc["@mozilla.org/network/simple-uri;1"]
.createInstance(Ci.nsIURI);
link.uri = uri3;
do_check_eq(link.uriHash, "hTrpDwNRMkvXPqYV5kh1Fw==");
}
function test_links()
{
// links:
var link1 = Cc["@mozilla.org/windows-jumplistlink;1"]
.createInstance(Ci.nsIJumpListLink);
var link2 = Cc["@mozilla.org/windows-jumplistlink;1"]
.createInstance(Ci.nsIJumpListLink);
var uri1 = Cc["@mozilla.org/network/simple-uri;1"]
.createInstance(Ci.nsIURI);
var uri2 = Cc["@mozilla.org/network/simple-uri;1"]
.createInstance(Ci.nsIURI);
uri1.spec = "http://www.test.com/";
uri2.spec = "http://www.test.com/";
link1.uri = uri1;
link1.uriTitle = "Test";
link2.uri = uri2;
link2.uriTitle = "Test";
do_check_true(link1.equals(link2));
link2.uriTitle = "Testing";
do_check_false(link1.equals(link2));
link2.uriTitle = "Test";
uri2.spec = "http://www.testing.com/";
do_check_false(link1.equals(link2));
}
function test_shortcuts()
{
// shortcuts:
var sc = Cc["@mozilla.org/windows-jumplistshortcut;1"]
.createInstance(Ci.nsIJumpListShortcut);
var handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"]
.createInstance(Ci.nsILocalHandlerApp);
handlerApp.name = "TestApp";
handlerApp.detailedDescription = "TestApp detailed description.";
handlerApp.appendParameter("-test");
sc.iconIndex = 1;
do_check_eq(sc.iconIndex, 1);
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).
QueryInterface(Ci.nsIDirectoryService);
var notepad = dirSvc.get("WinD", Ci.nsIFile);
notepad.append("notepad.exe");
if (notepad.exists()) {
handlerApp.executable = notepad;
sc.app = handlerApp;
do_check_eq(sc.app.detailedDescription, "TestApp detailed description.");
do_check_eq(sc.app.name, "TestApp");
do_check_true(sc.app.parameterExists("-test"));
do_check_false(sc.app.parameterExists("-notset"));
}
}
function test_jumplist()
{
// Jump lists can't register links unless the application is the default
// protocol handler for the protocol of the link, so we skip off testing
// those in these tests. We'll init the jump list for the xpc shell harness,
// add a task item, and commit it.
// not compiled in
if (Ci.nsIWinTaskbar == null)
return;
var taskbar = Cc["@mozilla.org/windows-taskbar;1"]
.getService(Ci.nsIWinTaskbar);
var builder = taskbar.createJumpListBuilder();
do_check_neq(builder, null);
// Win7 and up only
try {
var sysInfo = Cc["@mozilla.org/system-info;1"].
getService(Ci.nsIPropertyBag2);
var ver = parseFloat(sysInfo.getProperty("version"));
if (ver < 6.1) {
do_check_false(builder.available, false);
return;
}
} catch (ex) { }
do_check_true(taskbar.available);
builder.deleteActiveList();
var items = Cc["@mozilla.org/array;1"]
.createInstance(Ci.nsIMutableArray);
var sc = Cc["@mozilla.org/windows-jumplistshortcut;1"]
.createInstance(Ci.nsIJumpListShortcut);
var handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"]
.createInstance(Ci.nsILocalHandlerApp);
handlerApp.name = "Notepad";
handlerApp.detailedDescription = "Testing detailed description.";
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).
QueryInterface(Ci.nsIDirectoryService);
var notepad = dirSvc.get("WinD", Ci.nsIFile);
notepad.append("notepad.exe");
if (notepad.exists()) {
handlerApp.executable = notepad;
sc.app = handlerApp;
items.appendElement(sc, false);
var removed = Cc["@mozilla.org/array;1"]
.createInstance(Ci.nsIMutableArray);
do_check_true(builder.initListBuild(removed));
do_check_true(builder.addListToBuild(builder.JUMPLIST_CATEGORY_TASKS, items));
do_check_true(builder.addListToBuild(builder.JUMPLIST_CATEGORY_RECENT));
do_check_true(builder.addListToBuild(builder.JUMPLIST_CATEGORY_FREQUENT));
do_check_true(builder.commitListBuild());
builder.deleteActiveList();
do_check_true(builder.initListBuild(removed));
do_check_true(builder.addListToBuild(builder.JUMPLIST_CATEGORY_CUSTOM, items, "Custom List"));
do_check_true(builder.commitListBuild());
builder.deleteActiveList();
}
}
function run_test()
{
var isWindows = ("@mozilla.org/windows-registry-key;1" in Components.classes);
if (!isWindows)
return;
test_basics();
test_separator();
test_hashes();
test_links();
test_shortcuts();
test_jumplist();
}