[gnome-panel/wip/segeiger/reference-documentation: 7/7] doc/reference/panel-applet: Improve reference documentation
- From: Sebastian Geiger <segeiger src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-panel/wip/segeiger/reference-documentation: 7/7] doc/reference/panel-applet: Improve reference documentation
- Date: Sun, 23 Aug 2015 22:56:42 +0000 (UTC)
commit 2e887528a228732cc73780448d48e7b4e21d5879
Author: Sebastian Geiger <sbastig gmx net>
Date: Mon Aug 24 00:53:29 2015 +0200
doc/reference/panel-applet: Improve reference documentation
doc/reference/panel-applet/Makefile.am | 3 +-
doc/reference/panel-applet/add_to_panel.png | Bin 0 -> 50415 bytes
doc/reference/panel-applet/panel-applet-docs.sgml | 378 +++++++++++++++------
3 files changed, 281 insertions(+), 100 deletions(-)
---
diff --git a/doc/reference/panel-applet/Makefile.am b/doc/reference/panel-applet/Makefile.am
index 85aa486..0ffe4ba 100644
--- a/doc/reference/panel-applet/Makefile.am
+++ b/doc/reference/panel-applet/Makefile.am
@@ -35,7 +35,8 @@ IGNORE_HFILES = \
panel-applet-marshal.h
# Images to copy into HTML directory.
-HTML_IMAGES =
+HTML_IMAGES = \
+ add_to_panel.png
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
content_files = \
diff --git a/doc/reference/panel-applet/add_to_panel.png b/doc/reference/panel-applet/add_to_panel.png
new file mode 100644
index 0000000..0d6f05f
Binary files /dev/null and b/doc/reference/panel-applet/add_to_panel.png differ
diff --git a/doc/reference/panel-applet/panel-applet-docs.sgml
b/doc/reference/panel-applet/panel-applet-docs.sgml
index 7cf7c4e..bd877dc 100644
--- a/doc/reference/panel-applet/panel-applet-docs.sgml
+++ b/doc/reference/panel-applet/panel-applet-docs.sgml
@@ -16,20 +16,45 @@
</bookinfo>
<part id="overview">
- <title>Panel Applet Library Overview</title>
+ <title>Panel Applet Library Overview</title>
+ <partintro>
+ <para>
+ The Panel Applet Library is used in the GNOME Flashback desktop to write applets that can be added
to GNOME
+ Panel. GNOME Panel is the main user interface used in the GNOME Flashback desktop environment,
through which
+ users interact with their computer and open applications.
+ </para>
- <para>
- Applets are small applications that are embedded in the GNOME panel. They can be used to give quick
access to some features, or to display the state of something specific.
- </para>
+ <para>
+ Applets are small applications that are embedded in the GNOME Panel. They can be used to give quick
access
+ to some features, or to display the state of something specific. Most features in GNOME Panel such
as the clock,
+ the application menu, the calendar and many others are written with this Panel Applet Library.
Applets are added
+ through the "Add to Panel" dialog which can be opened from the "Add to Panel..." option on the
context menu of
+ a GNOME Panel.
+ </para>
- <para>
- The Panel Applet library is what should be used to write applets as it handles all the communication
with the GNOME panel. It hides all of the embedding process of the applet behind a <link
linkend="PanelApplet"><type>PanelApplet</type></link> widget. It also provides <link
linkend="PanelApplet"><type>PanelApplet</type></link> API to properly integrate the applet in the panel.
- </para>
+ <mediaobject>
+ <imageobject>
+ <imagedata align="center" fileref="add_to_panel.png" format="PNG"/>
+ </imageobject>
+ </mediaobject>
- <note><simpara>
- The Panel Applet library development continues as part of the GNOME Flashback project. The default
desktop of GNOME (e.g. GNOME Shell) uses a different system, so
- an applet written for the Panel Applet library will not be usable in the default GNOME that users may
use.
- </simpara></note>
+ <para>
+ The Panel Applet Library is what should be used to write applets as it handles all the communication
with
+ the GNOME panel. It hides all of the embedding process of the applet behind a
+ <link linkend="PanelApplet"><type>PanelApplet</type></link> widget. It also provides
+ <link linkend="reference"><type>PanelApplet API</type></link> to properly integrate the applet in the
+ panel.
+ </para>
+
+ <note>
+ <simpara>
+ The Panel Applet Library was original part of the default GNOME desktop but was deprecated with
GNOME 3,
+ when GNOME Shell was released. Nowadays development continues as part of the GNOME Flashback
project. The
+ default desktop of GNOME now uses GNOME Shell, which uses a different system for extension, so an
applet
+ written with the Panel Applet Library will not be usable in the default GNOME that users may use.
+ </simpara>
+ </note>
+ </partintro>
</part>
@@ -40,56 +65,179 @@
<title>Introduction</title>
<para>
- While applets are rather simple to write, they are not the most easy form of interaction to users for
two reasons: it is not intuitive how to add or remove applets for many users, and the restriction in size of
applets can limit their interface. Therefore, before writing an applet, think hard whether this is the form
of interaction that is best for the feature you want to provide.
+ While applets are rather simple to write, they are not the most easy form of interaction to users for
two reasons:
+ <itemizedlist>
+ <listitem>
+ It is not intuitive how to add or remove applets for many users, so users may not know about
your applet,
+ or may not know how to add it to the GNOME Panel.
+ </listitem>
+ <listitem>
+ The restriction in size of applets can limit their interface, so you should only use applets for
simple
+ tasks such as displaying information, or for controlling other applications and programs.
+ </listitem>
+ </itemizedlist>
+ Therefore, before writing an applet, think hard whether this is the form of interaction that
+ is best for the feature you want to provide.
</para>
- <note><simpara>
- Keep in mind that starting with GNOME 3, the panel and applets are only available in the fallback mode.
An applet will therefore not be usable in the default GNOME that users may use.
- </simpara></note>
-
</chapter>
<chapter id="getting-started.concepts">
<title>Concepts</title>
- <sect2 id="getting-started.concepts.applet-types">
- <title>Applet Types</title>
-
- <para>
- The applet type is the identifier representing a type of applets to the panel. It is a simple string,
like <constant>HelloWorldApplet</constant> and is unique per <link
linkend="getting-started.concepts.applet-factory">applet factory</link>.
- </para>
-
- </sect2>
-
- <sect2 id="getting-started.concepts.applet-factory">
- <title>Applet Factory</title>
-
- <para>
- The applet factory is an implementation detail that is mostly hidden by the Panel Applet library, but
it still appears in a few places (<link
linkend="PANEL-APPLET-OUT-PROCESS-FACTORY:CAPS"><function>PANEL_APPLET_OUT_PROCESS_FACTORY()</function></link>,
<link
linkend="PANEL-APPLET-IN-PROCESS-FACTORY:CAPS"><function>PANEL_APPLET_IN_PROCESS_FACTORY()</function></link>
and <link linkend="getting-started.install.panel-applet"><filename>.panel-applet</filename> files</link>) so
it is important to understand what is an applet factory.
- </para>
-
- <para>
- The applet factory is the object that will create a new applet instance when the panel requests a new
applet to be created. It is identified with a simple string id, for example
<constant>HelloWorldFactory</constant>.
- </para>
-
- <para>
- The requests the applet factory will receive from the panel specify which type of applet should be
created. This is what makes it possible to have more than one applet types in one applet binary. In most
cases, however, the applet factory will be specific to only one applet type. The map between applet types and
the applet factory is recorded in <link
linkend="getting-started.install.panel-applet"><filename>.panel-applet</filename> files</link>.
- </para>
-
- <para>
- There is only one applet factory per applet binary, and it is always running before any applet
instance is created by the applet binary. The applet factory is created via <link
linkend="PANEL-APPLET-OUT-PROCESS-FACTORY:CAPS"><function>PANEL_APPLET_OUT_PROCESS_FACTORY()</function></link>
or <link
linkend="PANEL-APPLET-IN-PROCESS-FACTORY:CAPS"><function>PANEL_APPLET_IN_PROCESS_FACTORY()</function></link>.
- </para>
-
- </sect2>
-
- <sect2 id="getting-started.concepts.applet-instances">
- <title>Applet Instances</title>
-
- <para>
- There is no restriction as to how many instances of one applet type can be created. The user might
choose to add more than one <constant>HelloWorldApplet</constant> applets to his panels. This can have some
implications on the design used to write applets. The most important implication is that it is generally
wrong to have global variables to keep a state specific to an applet instance.
- </para>
+ <para>
+ In order to write an applet it is important to understand the relationships between GNOME Panel and
your
+ applets. For example, how are applets registered to the GNOME Panel? How does the GNOME Panel
instantiate an
+ applet?
+ </para>
+ <para>
+ On a typical desktop there can be multiple GNOME Panels and each GNOME Panel can have several
instances of
+ your applet. These different instances are created by an <emphasis>applet factory</emphasis> which
must be
+ registered to the GNOME Panel. Additionally, in order to identify your applet and instantiate the
correct
+ applet, each applet is identified by an <emphasis>applet type</emphasis>.
+ </para>
- </sect2>
+ <sect1>
+ <title>Applet Registration</title>
+
+ <para>
+ To make your applets and the applet factory known to GNOME Panel - so that it can show your
+ applet in the list of applets of the "Add to Panel" dialog - and to add applets to the panel,
you
+ must create a Panel Applet File.
+ <link linkend="getting-started.install.panel-applet">Panel Applet files</link> are introduced
in more
+ detail later in this document. However it is important for applet authors to understand the
relationship
+ between <emphasis>the panel applet file</emphasis>, <emphasis>the applet factory</emphasis>,
and the
+ <emphasis>applet type</emphasis>. Therefore this section contains a short example of a Panel
Applet file.
+ </para>
+
+ <sect2>
+ <title>Panel Applet Files</title>
+ <para>
+ <link linkend="getting-started.install.panel-applet">Panel Applet files</link> are
+ <constant>ini</constant>-file formatted files that contain the necessary information
about your
+ factory and your applet types. The following example listing shows a simple Panel Applet
file.
+ </para>
+ <informalexample>
+ <programlisting>
+ [Applet Factory]
+ Id=HelloWorldFactory
+ Name=Hello World Applet Factory
+ Description=Factory for the window navigation related applets
+
+ [HelloWorldApplet]
+ Name=Hello World
+ Description=Factory for the Hello World applet example
+ Icon=hello-world-icon
+ </programlisting>
+ </informalexample>
+ </sect2>
+
+ <sect2 id="getting-started.concepts.applet-types">
+ <title>Applet Types</title>
+
+ <para>
+ The applet type is the identifier representing a type of applets to the panel. It is a
simple string,
+ like <constant>HelloWorldApplet</constant> and is unique per
+ <link linkend="getting-started.concepts.applet-factory">applet factory</link>.
+ </para>
+
+ <note>
+ <simpara>
+ In the example listing above the applet type can be found in the second section title
+ (e.g. <constant>[HelloWorldApplet]</constant>, but without the square brackets).
+ </simpara>
+ </note>
+ </sect2>
+
+ <sect2 id="getting-started.concepts.applet-factory">
+ <title>Applet Factory</title>
+
+ <para>
+ The applet factory is an implementation detail that is mostly hidden by the Panel Applet
Library,
+ but it still appears in a few places such as:
+ <itemizedlist>
+ <listitem>
+ <para>
+ The <link linkend="PANEL-APPLET-OUT-PROCESS-FACTORY:CAPS">
+ <function>PANEL_APPLET_OUT_PROCESS_FACTORY()</function></link> macro, which is used
to build
+ out process applets. It gets the factory id passed as its first parameter.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <link linkend="PANEL-APPLET-IN-PROCESS-FACTORY:CAPS">
+ <function>PANEL_APPLET_IN_PROCESS_FACTORY()</function></link> macro, which is used
to build in
+ process applets. It gets the factory id passed as its first parameter.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A Panel Applet file, which is used to register applet types and the applet factory
to the
+ GNOME Panel. It must contain the same applet factory id as used in the above two
macros.
+ </para>
+ <warning>
+ <simpara>By default applets are out-process, if you have used the
+ <function>PANEL_APPLET_IN_PROCESS_FACTORY</function>, then you must add:
+ <constant>InProces=true</constant> to the <constant>[Applet
Factory]</constant>
+ section.
+ </simpara>
+ </warning>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The applet factory is the object that will create a new applet instance when the panel
requests a
+ new applet to be created. It is identified with a simple string id, for example
+ <constant>HelloWorldFactory</constant>.
+ </para>
+
+ <note>
+ <simpara>
+ In the example listing above the applet factory id can be found in the
+ <constant>ID</constant>-field of the <constant>[Applet Factory]</constant> section.
+ </simpara>
+ </note>
+
+ <para>
+ The requests the applet factory will receive from the GNOME Panel specify which type of
applet should be created.
+ This is what makes it possible to have more than one applet type in one applet binary. In
most cases, however, the
+ applet factory will be specific to only one applet type.
+ </para>
+
+ <para>
+ There is only one applet factory per applet binary, and it is always running before any
applet instance is
+ created by the applet binary. The applet factory is created via one of these two macros:
+ <itemizedlist>
+ <listitem>
+ <para><link
linkend="PANEL-APPLET-OUT-PROCESS-FACTORY:CAPS"><function>PANEL_APPLET_OUT_PROCESS_FACTORY()</function></link></para>
+ </listitem>, or
+ <listitem>
+ <para><link
linkend="PANEL-APPLET-IN-PROCESS-FACTORY:CAPS"><function>PANEL_APPLET_IN_PROCESS_FACTORY()</function></link></para>
+ </listitem>.
+ </itemizedlist>
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="getting-started.concepts.applet-instances">
+ <title>Applet Instances</title>
+ <para>
+ There is no restriction as to how many instances of one applet type can be created. The user
might
+ choose to add more than one <constant>HelloWorldApplet</constant> applets to his panels. This
can
+ have some implications on the design used to write applets. The most important implication is
that
+ it is generally wrong to have global variables to keep a state specific to an applet instance.
+
+ <warning>
+ <simpara>
+ Using global variables in an applet can cause problems when the applet is instantiated
+ several times.
+ </simpara>
+ </warning>
+ </para>
+ </sect1>
</chapter>
@@ -97,7 +245,57 @@
<title>Hello World Example</title>
<para>
- An example is worth a million words, so here is a simple one:
+ In this section we will write a simple example applet. This simple applet will have no functionality
and
+ only displays a label with "Hello World" on the panel. For this simple applet only following three
parts
+ are needed:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <link linkend="PANEL-APPLET-OUT-PROCESS-FACTORY:CAPS">
+ <function>PANEL_APPLET_OUT_PROCESS_FACTORY()</function>
+ </link>: this creates an <link linkend="getting-started.concepts.applet-factory">applet
factory</link> named
+ <constant>HelloWorldFactory</constant>, and each time our applet is added to a GNOME Panel,
this applet
+ factory will create an applet instance, and calls
<function>hello_world_factory_callback()</function>
+ with a <link linkend="PanelApplet"><type>PanelApplet</type></link> object already created.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>hello_world_factory_callback()</function>: this checks if the request to create an
applet
+ instance is for an <link linkend="getting-started.concepts.applet-types">applet type</link>
supported
+ by our <link linkend="getting-started.concepts.applet-factory">applet factory</link>. Here we
can see
+ that we only support the <constant>HelloWorldApplet</constant> applet type. This function
returns
+ <constant>TRUE</constant> on success and <constant>FALSE</constant> on failures.
+
+ <note>
+ <simpara>If you return <constant>FALSE</constant> here, GNOME Panel will show a dialog and
+ notify the user that the applet loading failed.</simpara>
+ </note>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>hello_world_applet_start()</function>: this is where we actually setup the
+ <link linkend="PanelApplet"><type>PanelApplet</type></link> widget for the work the applet
should do.
+ This can include adding widgets to the applet, connecting to signals, loading settings via
GSettings,
+ etc.
+
+ <note>
+ <simpara>
+ The PanelApplet is a subclass of <link linkend="GtkBin"><type>GtkBin</type></link>
+ container, to add more than one widget to it you will need to use another GtkContainer
+ implementation such as <link linkend="GtkBox"><type>GtkBox</type></link> or
+ <link linkend="GtkGrid"><type>GtkGrid</type></link>.
+ </simpara>
+ </note>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ An example is worth a million words, so here is the code for our <emphasis>Hello World</emphasis>
applet.
</para>
<example id="getting-started.example.simple">
@@ -106,7 +304,7 @@
#include <gtk/gtk.h>
#include <panel-applet.h>
-static gboolean
+static void
hello_world_applet_start (PanelApplet *applet)
{
GtkWidget *label;
@@ -114,8 +312,6 @@ hello_world_applet_start (PanelApplet *applet)
label = gtk_label_new ("Hello World");
gtk_container_add (GTK_CONTAINER (applet), label);
gtk_widget_show_all (GTK_WIDGET (applet));
-
- return TRUE;
}
static gboolean
@@ -123,12 +319,12 @@ hello_world_factory_callback (PanelApplet *applet,
const gchar *iid,
gpointer data)
{
- gboolean retval = FALSE;
+ if (g_strcmp0 (iid, "HelloWorldApplet") != 0)
+ return FALSE;
- if (g_strcmp0 (iid, "HelloWorldApplet") == 0)
- retval = hello_world_applet_start (applet);
+ hello_world_applet_start (applet);
- return retval;
+ return TRUE;
}
PANEL_APPLET_OUT_PROCESS_FACTORY ("HelloWorldFactory",
@@ -139,29 +335,12 @@ PANEL_APPLET_OUT_PROCESS_FACTORY ("HelloWorldFactory",
</example>
<para>
- Here are the few things that are important in this example:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- <link
linkend="PANEL-APPLET-OUT-PROCESS-FACTORY:CAPS"><function>PANEL_APPLET_OUT_PROCESS_FACTORY()</function></link>:
this creates an <link linkend="getting-started.concepts.applet-factory">applet factory</link> named
<constant>HelloWorldFactory</constant>, and each time this applet factory will create an applet instance, it
will call <function>hello_world_factory_callback()</function> with a <link
linkend="PanelApplet"><type>PanelApplet</type></link> object already created.
- </para>
- </listitem>
- <listitem>
- <para>
- <function>hello_world_factory_callback()</function>: this checks if the request to create an applet
instance is for an <link linkend="getting-started.concepts.applet-types">applet type</link> supported by the
<link linkend="getting-started.concepts.applet-factory">applet factory</link>. Here we can see that we only
support the <constant>HelloWorldApplet</constant> applet type. This function returns
<constant>TRUE</constant> on success and <constant>FALSE</constant> on failures.
- </para>
- </listitem>
- <listitem>
- <para>
- <function>hello_world_applet_start()</function>: this is where we actually setup the <link
linkend="PanelApplet"><type>PanelApplet</type></link> widget for the work the applet should do. This can
include filling the widget, connecting to signals, etc.
- </para>
- </listitem>
- </itemizedlist>
-
- <para>
- While the previous example is simple, it can be useful to directly subclass the <link
linkend="PanelApplet"><type>PanelApplet</type></link> type. This makes it easy to have a per-applet instance
private structure, among other benefits.
+ While the previous example is simple, it can be useful to directly subclass the
+ <link linkend="PanelApplet"><type>PanelApplet</type></link> type. This makes it easy to have a
per-applet
+ instance private structure, among other benefits. Most of the code below is related to the GObject
system
+ and needed to subclass the Panel Applet. The only noteworthy difference is that the
+ <constant>PANEL_APPLET_OUT_PROCESS_FACTORY</constant> macro now takes our subclassed type (e.g.
<constant>HELLO_WORLD_TYPE_APPLET</constant>)
+ as its second parameter, instead of <constant>PANEL_TYPE_APPLET</constant>.
</para>
<example id="getting-started.example.subclass">
@@ -213,12 +392,10 @@ hello_world_applet_class_init (HelloWorldAppletClass *klass)
g_type_class_add_private (class, sizeof (HelloWorldAppletPrivate));
}
-static gboolean
+static
hello_world_applet_start (HelloWorldApplet *applet)
{
gtk_widget_show (GTK_WIDGET (applet));
-
- return TRUE;
}
static gboolean
@@ -226,17 +403,17 @@ hello_world_factory_callback (HelloWorldApplet *applet,
const gchar *iid,
gpointer data)
{
- gboolean retval = FALSE;
+ if (g_strcmp0 (iid, "HelloWorldApplet") != 0)
+ return FALSE;
- if (g_strcmp0 (iid, "HelloWorldApplet") == 0)
- retval = hello_world_applet_start (applet);
+ hello_world_applet_start (applet);
- return retval;
+ return TRUE;
}
PANEL_APPLET_OUT_PROCESS_FACTORY ("HelloWorldFactory",
HELLO_WORLD_TYPE_APPLET,
- (PanelAppletFactoryCallback) hello_world_factory_callback,
+ hello_world_factory_callback,
NULL)
</programlisting>
</example>
@@ -247,10 +424,11 @@ PANEL_APPLET_OUT_PROCESS_FACTORY ("HelloWorldFactory",
<title>Using a Context Menu</title>
<para>
- The Panel Applet library uses <type>GtkAction</type> to define menu items appearing in the context menu
of the applet.
+ The Panel Applet library uses <type>GAction</type> to define menu items appearing in the context menu
of the
+ applet.
</para>
- <sect2 id="getting-started.context-menu.content">
+ <sect1 id="getting-started.context-menu.content">
<title>Guidelines for Context Menu</title>
<para>
@@ -270,19 +448,21 @@ PANEL_APPLET_OUT_PROCESS_FACTORY ("HelloWorldFactory",
</listitem>
<listitem>
<para>
- Avoid putting a "Help" menu item. The user will usually explicitly add the applet, so it is expected
that he knows what the applet is about. Putting a "Help" menu item in the context menu is therefore too
prominent. It might make sense to add a "Help" button in the Preferences dialog, though.
+ Avoid putting a "Help" menu item. The user will usually explicitly add the applet, so it is expected
that he knows what the applet is about.
+ Putting a "Help" menu item in the context menu is therefore too prominent. It might make sense to
add a "Help" button in the Preferences dialog, though.
</para>
</listitem>
<listitem>
<para>
- If you agree, avoid putting a "About" menu item. To the user, applets are not different applications
but elements of one global application, the panel. Of course, this means that credits for working on the
applet are not visible to the user.
+ If you agree, avoid putting a "About" menu item. To the user, applets are not different applications
but elements of one global application, the panel. Of course, this means that credits
+ for working on the applet are not visible to the user.
</para>
</listitem>
</itemizedlist>
- </sect2>
+ </sect1>
- <sect2 id="getting-started.context-menu.setup">
+ <sect1 id="getting-started.context-menu.setup">
<title>Setting Up the Menu</title>
<para>
@@ -415,7 +595,7 @@ PANEL_APPLET_OUT_PROCESS_FACTORY ("HelloWorldFactory",
</listitem>
</itemizedlist>
- </sect2>
+ </sect1>
<sect2 id="getting-started.context-menu.xml-file">
<title>Menu XML File</title>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]