My favorites | English | Sign in

Google Desktop APIs (Labs)

Creating a Gadget

Contents

Introduction

This page tells you how to create a Desktop gadget using JavaScript, XML, and the Gadget API. Many of the details of creating a gadget are handled by the Gadget Designer. Once you're writing code, you'll probably want to refer to the Gadget API Reference.

To develop and distribute a Desktop gadget, you need to do the following (with the help of Gadget Designer):

  • Create a gadget.gmanifest file in XML that contains meta-information about the gadget.
  • Create a main.xml file, which defines the main view of your gadget. A view consists of the UI and objects that completely make up one visible pane of your gadget.
  • If needed, create an options.xml file, which defines your gadget's options view.
  • Write code to implement your gadget's functionality.
  • Zip together gadget.gmanifest, main.xml, options.xml (if you have one), and any separate JavaScript files. If you hand-zip the file instead of creating it with Gadget Designer, rename the zipped file so it has a .gg suffix (for Google Gadget).

When a user installs a .gg-file-based gadget, their Google Desktop installation handles unzipping, installing, and registering it, using information from the gadget.gmanifest file.

Note: Although you might see some old gadgets in .exe files, all new gadgets must be in .gg files.

Back to top

What Goes into a gadget.gmanifest File

Your gadget's gadget.gmanifest file specifies, in XML format, metadata describing the gadget, as well as components that need to be installed before gadget creation.

The manifest file content consists of a <gadget> element, which has an attribute of minimumGoogleDesktopVersion with a value of the oldest version of Google Desktop that can run this gadget. Inside this element, you define a required <about> element, a recommended <platform> element, and an optional <install> element.

The about Element

The following table shows the elements that the <about> element can include. The columns on the right show where the value of each element is used. For example, the value of the <name> element is used in gadget listings — the Add gadgets window, online gadget directories, and the web page automatically generated for each gadget — as well as in the Developers' Hall of Fame and the gadget's user interface.

Note: You can always specify element values directly, like this: <version>1.0.0.0</version>. Alternatively, a few elements (<name>, <description>, and <aboutText>) can have a value that refers to a variable defined in strings.xml. For example, <name>&GADGET_NAME;</name> refers to the value of the <GADGET_NAME> element in the current locale's strings.xml file. Don't use a variable unless the element description says the value can be a variable.

Element Description Where Used
Listings
Hall of Fame
UI
Other/Notes
<id> The gadget's CLSID. Generate this string using a tool such as Gadget Designer, uuidgen, or an online [uuid generator].       Used by Google Desktop to differentiate between gadgets. This value must be unique for each gadget, and it should remain the same when the gadget is updated.
<name> The gadget's name. The value can be a variable defined in strings.xml.
used in gadget listings
used in Developers' Hall of Fame
used in gadget UI
 
<description> A short description of what the gadget does. The value can be a variable defined in strings.xml.
used in gadget listings
 
used in gadget UI
Used in the gadget installation dialog, as well as the gadget's automatically generated web page.
<version> The gadget's version number. Example:

<version>1.0.0.0</version>
      Used by Google Desktop to check whether the online version of the gadget is newer than the cached version.
<author> The name of the person or company that wrote the gadget.
used in gadget listings
used in Developers' Hall of Fame
  Also used as part of the gadget filename in the user's My Google Gadgets folder.
<authorEmail> An email address for contacting the developer.
used in gadget listings
used in Developers' Hall of Fame
  Used by Google and users of your gadget to contact you. Also used to attribute gadgets to the developer for the Developers' Hall of Fame. If you're concerned about receiving spam, consider using an alternate email address.
<category> One or two categories that describe the gadget. A gadget has exactly one <category> tag. Possible values: communication, finance, fun_games, google, holiday, lifestyle, news, sports, technology, tools. Example:

<category>fun_games</category>

Another example:

<category>news,sports</category>
used in gadget listings
    Used in gadget listings. For example, when the user clicks News in the Add gadgets dialog or an online gadget directory, only gadgets that have the category news appear.
<thumbnailUrl> The URL for a 80x60-pixel image that represents your gadget.
used in gadget listings
    Used to represent your gadget in gadget listings where space is limited.

Once your gadget is published, you can update its images in two ways. You can change the values of thumbnailUrl and screenshotUrl in the manifest for your gadget's .gg file. Or you can just update the images, while retaining the same URLs.
<screenshotUrl> The URL for a 300x225-pixel image that features a screenshot of your gadget.
used in gadget listings
    Used to represent your gadget in the web page that's automatically generated for each gadget.

For more information, see the description of <thumbnailUrl>.
<authorWebsite>
(optional)
The URL for a page that describes the gadget.
used in gadget listings
used in Developers' Hall of Fame
  Used for the "Learn more" link in the gadget's listings.
<copyright>
(optional)
A copyright notice.
used in gadget listings
     
<aboutText>
(optional)
Text for the About dialog. The value can be a variable defined in strings.xml. The About text should have at least three lines, using the following format:

Gadget Name
Copyright/License
Gadget description paragraph.

   
used in gadget UI
 
<smallIcon>
(optional)
A 24x24-pixel icon, preferably a PNG with transparency.    
used in gadget UI
Used to represent the gadget, such as when the gadget is collapsed.
<icon>
(optional)
A 32x32-pixel icon.    
used in gadget UI
Used in the gadget's About dialog.
<displayAPI>
(optional)
When the usesNotifier attribute is set to true, enables sidebar UI notifications for content items. Registration is handled automatically. Example:

<displayAPI usesNotifier="true" />
       
<eventAPI>
(optional)
If this element is included, the gadget can use the Event API. Registration is handled automatically. Example:

<eventAPI />
       
<queryAPI>
(optional)
When allowModifyIndex is set to true, allows the gadget to use the Query API. Registration is handled automatically. Example:

<queryAPI allowModifyIndex="true" />
       
<personalizationAPI>
(optional)
When present, allows the gadget to use a personalization API such as the Ranking API. Registration is handled automatically. Example:

<personalizationAPI />
       

Here's an example of a gadget.gmanifest file:

<gadget minimumGoogleDesktopVersion="5.1.0.0">
  <about>
    <name>Gadget Name</name>
    <description>A few words about the gadget</description>
    <aboutText>Gadget Name
      Copyright (c) 2008 Some Company, Inc. All Rights Reserved
      Longer description of the gadget.</aboutText>
    <smallIcon>icon_small.png</smallIcon>
    <icon>icon_large.png</icon>
    <version>1.0.0.0</version>
    <author>Your Name</author>
    <authorWebsite>http://somecompany.com/gadgets.html</authorWebsite>
    <id>YOURCLSID-C739-4685-A470-F4FF5E7F47FB</id>
    <copyright>Copyright (c) 2008 Some Company, Inc. All Rights Reserved</copyright>
    <authorEmail>YourName.feedback+GadgetName@gmail.com</authorEmail>
    <category>fun_games</category>
  </about>
</gadget>

You must include (with values) the <id>, <name>, <description>, <version>, <author>, and <authorEmail> elements. We urge you to also include (with values) the <authorWebsite>, <copyright>, <aboutText>, <smallIcon>, and <icon> elements. You may see examples of the latter set of elements included without a value, such as <copyright></copyright>. This is acceptable, but not preferred.

Choosing an Email Address

We suggest that you use a single, dedicated email address for all of your gadgets. Using a dedicated address cuts down on spam to your personal account, and using a single address improves your chances of getting into the Developers' Hall of Fame.

One approach is to create a Gmail account with a login name such as helensmith.feedback. Then specify an <authorEmail> value of the form helensmith.feedback+gadgetname@gmail.com. Because Gmail ignores + and anything after it, email messages for all gadgets go to helensmith.feedback at gmail.com. To find the feedback for a particular gadget, search for to:gadgetname.

The platform Element

Use the <platform> element, along with the minimumGoogleDesktopVersion attribute of the <gadget> element, to specify the versions of Google Desktop that your gadget works with.

Inside the <platform> element, you define one element for each platform on which the gadget has been tested — <windows>, <mac>, or both. For each included element, define minimumGadgetHostVersion if the gadget works on that platform, or supported="no" if it doesn't.

Here are details on the elements that the <platform> element can include:

<windows>
Specifies the minimum version of Google Desktop for Windows required to run the gadget. You can find version numbers in the release notes.
<mac>
Specifies the minimum version of Google Gadgets for the Mac — a feature of Google Desktop for Mac — that's required to run the gadget. Specify the first version of Google Gadgets for the Mac with "1.0.0.0".

The following examples show typical uses of the <platform> element.

Gadget works on both Windows and Mac:

<gadget minimumGoogleDesktopVersion="5.1.0.0">
  <platform>
    <windows minimumGadgetHostVersion="5.1.0.0"/>
    <mac minimumGadgetHostVersion="1.0.0.0"/>
  </platform>
  ...
</gadget>

Gadget doesn't work on Mac:

<gadget minimumGoogleDesktopVersion="5.1.0.0">
  <platform>
    <windows minimumGadgetHostVersion="5.1.0.0"/>
    <mac supported="no"/>
  </platform>
  ...
</gadget>

Gadget not tested on Mac:

<gadget minimumGoogleDesktopVersion="5.1.0.0">
  <platform>
    <windows minimumGadgetHostVersion="5.1.0.0"/>
  </platform>
  ...
</gadget>

For more information, see Writing a Cross-Platform Gadget.

The install Element

The optional <install> element lists any package components that need to be installed before creating the gadget. For example to install a fonts package, include the <font> element:

<gadget ...>
  ...
  <install>
    <font src="mcfont.ttf"/>
  </install>
</gadget>

To include a COM dll or embed an ActiveX control with your gadget add the dll file to the package and use the <object> element to register the object:

<gadget ...>
  ...
  <install>
    <object name="myobject" clsid="OBJCLSID-HERE-..." src="my.dll"/>
  </install>
</gadget>

For the clsid property you can also use a progid in the format "progid:myobj_progid". To call methods on your embedded control from script do:

var obj = new myobject;
obj.MyMethod();

Back to top

What Goes into a View XML File

The Gadget API Reference lists the properties, methods, and events for elements that you can define in a gadget and its views (where "view" means the overall appearance of a pane). You use these elements in XML view files to specify the gadget's UI components, layout, and behavior. For your gadget's main view you need to write a main.xml XML file that defines a <view> element. If your gadget has an Options view, you also need to write an options.xml file which defines a different <view> element. Inside a <view> definition, you define the UI elements that make up that view. For example, a main.xml file might contain:

<view width="200" height="200">

  <button image="button.png" overImage="button_over.png"
   downImage="button_down.png" onclick="button_clicked()"/>

</view>

That defines a 200x200 pixel view that contains a button. We also specify, by setting the relevant button object properties, separate images for the button's normal, mouse-over, and mouse-down states. Via button's onclick event, when a user clicks the button, it calls the button_clicked() function, defined elsewhere.

To specify a property in XML, add property="value" to an element. You can specify an event scriptlet in XML by adding an event="script" to an element. As with DHTML, you can manipulate elements from a script once they're created, but only if they have a name property. For example:

<button name="sample_button" ... />

When an element has a name, scripts can access and manipulate it, as well as call any methods associated with it:

sample_button.property = "new value";
sample_button.event = "new script";
sample_button.method();

You can either use script functions defined elsewhere in your .gg file package, including in dedicated .js or .vbs files (such as the button_clicked() function used in the button example above), or you can include scripted functions within the <view> definition. For example:

<view width="200" height="200" onopen="view_onopen()">
 <script language="jscript"><!--
  function view_onopen()
  {
    foo( "bar()", 1000 );
  }

  function bar()
  {
    x = 2 + 2;
  }

 --></script>

 <div background="#FFFFFF" width="200" height="200"/>
</view>

Only one contentarea object can be defined inside a view object.

Note: For more help on defining views, see the article Using the Options Dialog.

Back to top

Gadget Event Handling

The gadget event model is similar to DHTML. For some objects — including view, basicElement, and some elements — the Gadget API Reference lists associated events. To specify how to handle an event for one of these objects, you put the event and what to do when it happens in the object's XML definition. For example, to specify what happens when a view object has an onmouseover event, you'd write:

<view
    onmouseover="do_something_when_mouse_is_over;"/>

...where do_something_when_mouse_is_over is a piece of script, such as alert('mouse over!'), or a call to a function implemented in a script block, such as view_onmouseover().

As with DHTML, events and their handlers have no arguments. Instead, the script uses the view.event object to learn about the event. Since only one event fires at a time, a view's event object contains information about the event currently being fired.

The event.returnValue property can be used to set a return value. As with DHTML, this value is a boolean that determines if the event's default behavior is fired. For example:

event.returnValue = false; // disable the default behavior
event.returnValue = true; // enable the default behavior
// don't specify a return value, enable the default behavior

In particular, the event.returnValue property can either:

  • view.event.returnValue = false; //Disable the view event's default behavior
  • view.event.returnValue = true; //Enable the view event's default behavior

For example:

<edit onkeypress="edit_onkeypress()"/>
function edit_onkeypress()
{
 if( event.keyCode == 'j' ) event.returnValue = false;
}

Each time you press a key when control is inside this edit object, the edit_onkeypress() function is called. If the key you press is j, then since the event.returnValue is set to false, the event and its usual return value are cancelled, making it as if the j was never pressed. Effectively, this <edit> element doesn't allow you to type the letter j.

Back to top

Internationalization

You should write your gadget to support having its text and labels appear in multiple languages, even if you can't supply any other-language text. Eventually, someone else may be able to do so. You can also specify different images, view layouts, or even scripts for different language users.

First, let's look at languages. To support multiple languages, all language-specific strings that will be visible in your gadget's UI must be placed in a file named strings.xml under subfolders named after the appropriate language ID. This file contains variable assignments for the strings in a particular language. Instead of using the language-specific strings in your gadget definition and code, use the variables instead. For example, Hello World's English strings.xml file contains:

<strings>

<GADGET_NAME>Hello World Sample Gadget</GADGET_NAME>
<GADGET_DESCRIPTION>Demonstrates a simple Google Desktop gadget</GADGET_DESCRIPTION>
<GADGET_COPYRIGHT>Copyright (c) 2006 Google Inc. All Rights Reserved</GADGET_COPYRIGHT>
<GADGET_WEBSITE>http://desktop.google.com/</GADGET_WEBSITE>
<GADGET_ABOUT>Hello World Sample Gadget
Copyright (c) 2006 Google Inc. All Rights Reserved
This gadget displays the text 'Hello World' on top of a picture using the main.xml design file. If the text is clicked on, a message box will show up as an event.</GADGET_ABOUT>

<HELLO_WORLD>Hello World!</HELLO_WORLD>

</strings>

In your script code for the Hello World gadget, you'd specify the "Hello World!" string as shown in this method invocation:

view.alert(HELLO_WORLD);

In your XML files you'd specify "Hello World!" as shown in this <label> element:

<label>&HELLO_WORLD;</label>

Note that in script code, you just use the element name from the strings.xml file. In XML, you need to preface the element name with an ampersand (&) and end it with a semicolon (;).

If you wrote your gadget to have both English and French versions, your files should be in the following hierarchy:

  YourGadget
       |
       |---- main.js
       |
       |---- main.xml
       |
       |---- other non-language-specific files...
       |
       |---- en (identifier for English)
       |      |
       |      `-- strings.xml
       |
       `---- fr (identifier for French)
              |
              `-- strings.xml

Note: Previously, this document used numeric codes for languages. For example, the preceding example used 1033 instead of en and 1036 instead of fr. We now recommend using modified RFC1766 language codes such as en, fr, fr_ca, and zh_cn. You can also provide a default version under a folder named 1033, since that will be used if no language matching the Google Desktop locale or the computer's current locale can be found.

Google Desktop first checks for a folder with a language ID that matches the installed version of Google Desktop. For example, the French version of Google Desktop looks for the fr folder. If Google Desktop finds the folder, it loads that folder's strings.xml file. If it cannot find that file, Google Desktop looks for the file in a folder whose name matches the computer's current Windows LCID (for example, 1036\strings.xml for France). If Google Desktop still cannot find the file, it looks for 1033\strings.xml.

Similarly, you can put images, markup, script, etc. in the localization folders, and Google Desktop will attempt to load them using the above rules. So, for example, if you have a gadget that requires a different image depending on the local language, you can use <img src="some_image.png"/>. Google Desktop will first try to load some_image.png. If that fails and you have the French version of Google Desktop, it will look for the file in the French localization folder (fr\some_image.png). If that fails, Google Desktop will look for the file in a folder that matches the system's Windows LCID (1036\some_image.png for France). If Google Desktop still doesn't find the file, it will look in the 1033 folder (1033\some_image.png).

You can put content in a localization folder instead of the main folder, including:

  • main.xml: If you need different layouts in different languages.
  • options.xml: If you need different layouts in different languages.
  • anything.js: If you need different scripts in different languages.

If you want to create a gadget that supports default behavior in most places but has different behavior in specific languages you can:

  • Put the gadget's main XML file in the root folder of your gadget.gg file.
  • Put the rest of the content in the 1033 folder of your gadget.gg file.
  • Place content that needs to be replaced in specific languages in the language-specific folder.

Back to top

APIs that a Gadget Can Use

This document discusses the Gadget API, but that's not the only API that gadgets can use. Any Desktop gadget can also use the following standard interfaces:

Core JavaScript features
Includes classes and objects such as Array, Date, Math, and RegExp.
Standard XMLHttpRequest class
Allows a gadget to request information from a website, or to send information.

Example: XMLHttpRequest (available online and in the SDK)
Article: Interacting With The Web: The XMLHttpRequest Object

W3C Level 1 DOM
Useful for parsing the results of an XMLHttpRequest.

Many powerful gadgets use only the preceding APIs. An advantage of sticking to these APIs is that your gadget can work on multiple platforms. For tips on writing gadgets that work on both Windows and Mac, see Writing a Cross-Platform Gadget.

If you want to tap into the power of Google Desktop, you can use the following Search APIs, which are available for Windows only:

Event API
Allows the gadget to be notified when Google Desktop indexes new items — for example, whenever the user opens a spreadsheet or loads a webpage. A gadget might use the Event API to detect when the user visits a particular website; the gadget could then display information that's related to the website.
Personalization API
Sorts clickable items so that the most relevant items (the ones the user is more likely to click) are displayed first.
Query API
Sends search queries to Google Desktop.

If you want still more APIs, you can include a COM DLL or embed an ActiveX control in your gadget, as described in The install Element. For sample code, see the HybridYesNoCancel example (available online and in the SDK).

Back to top

Object Overviews

In this section, we'll take a look at the various objects in the Gadget API, focusing on what they're used for and how they are related.

gadget Object

gadget has two subobjects, gadget.debug and gadget.storage, which are used for very different purposes at the overall gadget level.

  • gadget.debug helps with debugging by providing methods that display a string of your choice in the debug console when running in debug mode. To run in debug mode, unzip your gadget and, from the file you unzipped it to, double-click the gadget.gmanifest file. This lets you develop your gadget without having to zip it up each time you want to test it.
  • gadget.storage works with the files that make up the overall gadget package. Methods allow you to extract or open a file from the package. The filename arguments to the storage object can be any of the following:
    • "foo.xml" looks for foo.xml in the root folder of the .gg file. If it doesn't find it, it will look in the localization folders (e.g. en\foo.xml).
    • "subfolder\foo.xml" looks for foo.xml in the subfolder folder of the .gg file. If it doesn't find it, it will look in the subfolder folder of the localization folders (e.g. en\subfolder\foo.xml).
    • "c:\bar.xml" looks for bar.xml on the c:\ drive. You must provide the exact path.

view Object

You must define a view object for each overall pane appearance your gadget has. Each of these must be in a separate .XML file.

view's properties and methods define and access the overall behavior of a view pane. These include what UI elements make up the pane's appearance, the size of the pane, whether it's resizable by a user, timers that control script execution, adding or removing UI elements, and message/confirmation box display.

view's events fire and run a function based on various mouse button, key, resizing, property value change, or cursor actions, as well as when this view is first opened.

basicElement and UI Objects

basicElement is the parent object for the various UI elements that make up the visual appearance of a particular view. basicElement itself is never instantiated; it just provides a set of common properties and events for its descendant UI objects.

Properties specify the size and position of the element, its name, visibility and opacity, and other general UI element properties.

Events are the usual ones associated with a UI object; actions involving mouse clicks or the scroll wheel, dragging or dropping the element, receiving or losing keyboard focus, keys, and cursor movement.

You can define the following basicElement descendants:

  • button: Specific properties let you set various images for the button and its various states.
  • checkbox: Specific properties let you set various images for the checkbox and its various states, as well as determining if the box is checked or not. An event fires when the box's checked value changes.
  • object: An embedded windowless ActiveX control. Used primarily for Windows Media Player embedding.
  • contentarea: Contains a collection of contentItems.
  • div: Used to set element background colors or images.
  • edit: Specific properties let you control its text content's appearance and set or retrieve its text content. An event fires when the content changes.
  • img: Specific properties let you set the image to display and get its original dimensions. It also has an image resizing method.
  • label: Specific properties let you control the label text's appearance and position/alignment.
  • a: A link object with specific properties that let you control the link's appearance and its URL.
  • progressBar: Specific properties control the appearance of the progress bar and its components, as well as an event that fires when the value changes.

There is also the elements object, which represents a container of basicElement-descended objects.

options Object

Stores options and their values as a standard dictionary/map. You can set a value like this:

options.putValue("key", "value");

You can add items using either the putValue or the add method:

options.putValue("key", "value"); //Add or replace the current value.
options.add("key", "value"); // Add the value; if it already
                             // exists, do nothing.

The putDefaultValue method allows keys to return default values if the key does not have an actual value associated with it in the dictionary, removing the need for you to check if a value exists for that key. For example:

options.putDefaultValue("color", "red");

The dictionary now returns "red" whenever "color" is requested and "color" does not actually exist in the dictionary. For example:

options.putDefaultValue("color", "red");
options.putValue("color", "blue");
debug.trace(options.getValue("color"));   // displays "blue"
options.remove("color");
debug.trace(options.getValue("color"));   // displays "red" (the default)
options.putValue("texture", "bumpy");
debug.trace(options.getValue("texture")); // displays "bumpy"
options.remove("texture");
debug.trace(options.getValue("texture")); // displays "" (no default)

framework Namespace

The framework namespace exposes APIs that fill in gaps left by the Windows Scripting Host and are useful for gadget implementation. In particular, framework.* objects are not descended from basicElement and do not show up in gadget XML UI object definitions. framework is basically a .NET-like namespace of objects used to query for system information, which are used by scripts called by events on the XML-defined UI objects.

framework objects and their properties and methods allow you to:

  • Display Browse For File dialogs.
  • Load image files.
  • Get the current cursor location.
  • Get information about system memory capacity and usage.
  • Get information about the system's wireless capabilities and connection.
  • Set and monitor counters that control when script code runs.
  • Get information about the system's power source and battery capacity (both total and amount of power left).
  • Get information about the system's processor.
  • Get the system's screen dimensions.

Finally, there are two other defined objects used only for types within the Framework namespace:

  • point: Represents a point, with x- and y- coordinate properties.
  • size: Represents an object's size, with height and width properties.

As an example of how you might use framework objects, let's write a simple gadget that shows how much power is left on your laptop's battery:

<view width="200" height="200" onopen="view_onopen()">
 <script language="jscript"><!--
  function view_onopen()
  {
    setInterval( "update_battery()", 1000 );
  }

  function update_battery()
  {
    percent_used.innerText = system.power.percentRemaining + "%";
  }

 --></script>

 <div background="#FFFFFF" width="200" height="200"/>
 <label name="percent_used" align="center" valign="middle">0%</label>
</view>

We've defined a view that is 200x200 pixels with two elements in it:

  • a <div> with a background color of white
  • a <label> named percent_used that initially reads 0%.

When the gadget loads, the view onopen event fires, which calls view_onopen(). This function sets an interval so that update_battery() is called once every second. update_battery() uses the framework namespace's system.power.percentRemaining object and property to update the innerText of the percent_used element.

Note that we didn't have to put framework. before system.power.percentRemaining; it's your choice whether to do so or not.

Back to top