[libwnck] doc: Add some high-level documentation



commit 923f6fb7b25dabbe83d846acea09bb68e021fc1a
Author: Vincent Untz <vuntz gnome org>
Date:   Fri Feb 18 18:11:24 2011 +0100

    doc: Add some high-level documentation
    
    This includes hints as to when to use the library, common pitfalls and
    two simple examples.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=344137

 doc/Makefile.am                   |    2 +-
 doc/example-force-update.c        |   27 +++++++++
 doc/example-lazy-initialization.c |   51 ++++++++++++++++++
 doc/libwnck-docs.sgml             |  106 +++++++++++++++++++++++++++++++------
 4 files changed, 169 insertions(+), 17 deletions(-)
---
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 54cf3d0..57992bf 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -35,7 +35,7 @@ EXTRA_HFILES =
 HTML_IMAGES =
 
 # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE)
-content_files =
+content_files = example-force-update.c example-lazy-initialization.c
 
 # Other files to distribute
 extra_files =
diff --git a/doc/example-force-update.c b/doc/example-force-update.c
new file mode 100644
index 0000000..2d54d14
--- /dev/null
+++ b/doc/example-force-update.c
@@ -0,0 +1,27 @@
+#include <libwnck/libwnck.h>
+
+int
+main (int    argc,
+      char **argv)
+{
+  WnckScreen *screen;
+  WnckWindow *active_window;
+  GList *window_l;
+
+  gdk_init (&argc, &argv);
+
+  screen = wnck_screen_get_default ();
+
+  wnck_screen_force_update (screen);
+
+  active_window = wnck_screen_get_active_window (screen);
+
+  for (window_l = wnck_screen_get_windows (screen); window_l != NULL; window_l = window_l->next)
+    {
+      WnckWindow *window = WNCK_WINDOW (window_l->data);
+      g_print ("%s%s\n", wnck_window_get_name (window),
+                         window == active_window ? " (active)" : "");
+    }
+
+  return 0;
+}
diff --git a/doc/example-lazy-initialization.c b/doc/example-lazy-initialization.c
new file mode 100644
index 0000000..dca0598
--- /dev/null
+++ b/doc/example-lazy-initialization.c
@@ -0,0 +1,51 @@
+#include <libwnck/libwnck.h>
+
+static void
+on_window_opened (WnckScreen *screen,
+                  WnckWindow *window,
+                  gpointer    data)
+{
+  /* Note: when this event is emitted while screen is initialized, there is no
+   * active window yet. */
+
+  g_print ("%s\n", wnck_window_get_name (window));
+}
+
+static void
+on_active_window_changed (WnckScreen *screen,
+                          WnckWindow *previously_active_window,
+                          gpointer    data)
+{
+  WnckWindow *active_window;
+
+  active_window = wnck_screen_get_active_window (screen);
+
+  if (active_window)
+    g_print ("active: %s\n", wnck_window_get_name (active_window));
+  else
+    g_print ("no active window\n");
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+  GMainLoop *loop;
+  WnckScreen *screen;
+
+  gdk_init (&argc, &argv);
+
+  loop = g_main_loop_new (NULL, FALSE);
+  screen = wnck_screen_get_default ();
+
+  g_signal_connect (screen, "window-opened",
+                    G_CALLBACK (on_window_opened), NULL);
+  g_signal_connect (screen, "active-window-changed",
+                    G_CALLBACK (on_active_window_changed), NULL);
+
+  g_main_loop_run (loop);
+
+  g_main_loop_unref (loop);
+
+  return 0;
+}
diff --git a/doc/libwnck-docs.sgml b/doc/libwnck-docs.sgml
index 07aa26b..daf1c50 100644
--- a/doc/libwnck-docs.sgml
+++ b/doc/libwnck-docs.sgml
@@ -7,12 +7,13 @@
     <title>Libwnck Reference Manual</title>
   </bookinfo>
 
-  <part id="intro">
+  <part id="overview">
    <title>Libwnck Overview</title>
    <partintro>
     <para>
      libwnck is the Window Navigator Construction Kit, a library for use in writing pagers, tasklists, and more generally applications that are dealing with window management. It tries hard to respect the <ulink url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html";>Extended Window Manager Hints specification</ulink> (EWMH). The <ulink url="http://tronche.com/gui/x/icccm/";>Inter-Client Communication Conventions Manual</ulink> (ICCCM) is also a useful resource.
     </para>
+
     <para>
      libwnck depends on the following libraries:
      <variablelist>
@@ -32,21 +33,94 @@
     </para>
    </partintro>
   </part>
-  <!-- TODO
-  tell that wnck_set_client_type() should be used for pagers-like users
-  mention that the window/classgroup/application/workspace/screen are owned by libwnck and should not be ref'ed/unref'ed.
-  mention wnck_screen_force_update()
-
-Comment from Havoc:
-One thing you might emphasize is that libwnck is a very expensive
-library in some sense; every app using it is going to ask for a bunch of
-info from the X server, then use substantial resources continuing to
-mirror that info as it changes - pretty much every time anything changes
-on the display, every libwnck app will wake up.
-
-All panel applets share the same copy of libwnck so it isn't so bad in
-that case.
-  -->
+
+  <part id="getting-started">
+   <title>Getting Started with libwnck</title>
+
+   <refsect1 id="getting-started.use-cases">
+    <title>Use Cases</title>
+
+    <para>
+     Most users of libwnck should be tools that deal heavily with window management in one way or another: tasklists and pagers are obvious examples, but tools to automatically organize windows, to track resources of windows, or to inspect what is happening on a display can also be built with this library.
+    </para>
+
+    <para>
+     Applications that just need to do some management on their own windows (like positioning one of their windows on a specific workspace) should likely not use libwnck, as the use of this library is relatively expensive in terms of resources. The internals of libwnck make sure that the library always tracks everything that is occurring on the display, mirroring various information from the X server and actively using resources to update the cached information as it changes. In concrete termes, every time something changes on the display, every application using libwnck will wake up. An application that is not dealing specifically with window management should not do this.
+    </para>
+
+    <note><simpara>
+     When considering the use of libwnck, it makes sense to keep in mind the cost of the library. For example, it is possible to share this cost between various tools all dealing in one way or another with window management, by grouping them in the same process, even if from a UI perspective they all look like different applications.
+    </simpara></note>
+   </refsect1>
+
+   <refsect1 id="getting-started.pitfalls">
+    <title>Common Pitfalls</title>
+    <para>
+     While the API provided by libwnck should be mostly straight-forward in general, a few pitfalls are often hit by users of the library.
+    </para>
+
+    <sect2 id="getting-started.pitfalls.force-update">
+     <title>Explicit fetching of information</title>
+     <para>
+      At its creation, a <link linkend="WnckScreen"><type>WnckScreen</type></link> object will not have fetched information from the X server. If queried immediately after its creation (via <link linkend="wnck-screen-get-windows"><function>wnck_screen_get_windows()</function></link> or <link linkend="wnck-screen-get-workspaces"><function>wnck_screen_get_workspaces()</function></link>, for example), the <link linkend="WnckScreen"><type>WnckScreen</type></link> object will look like there are no workspaces nor windows on the screen. This information is fetched in the main event loop with an idle source, to avoid an expensive synchronous operation on startup. If no main event loop is used, or if the information is needed as soon as possible after the creation of the object, <link linkend="wnck-screen-force-update"><function>wnck_screen_force_update()</function></link> can be used to explicitly fetch the information.
+     </para>
+    </sect2>
+
+    <sect2 id="getting-started.pitfalls.lazy-initialization">
+     <title>Lazy initialization of WnckScreen objects and signals</title>
+     <para>
+      As mentioned above, a <link linkend="WnckScreen"><type>WnckScreen</type></link> object will have no information at its creation: it is lazily initialized during a main event loop. This lazy initialization will lead to the emission of many signals by the <link linkend="WnckScreen"><type>WnckScreen</type></link> object: for instance, the <link linkend="WnckScreen-window-opened"><function>"window-opened"</function></link> signal will be emitted for all <link linkend="WnckWindow"><type>WnckWindow</type></link> objects representing existing windows during the lazy initialization. This is actually a feature that enables you to easily initialize the state of your application, with the same code you will use to update its state when new windows get opened; there is an <link linkend="getting-started.examples.lazy-initialization">example</link> showing this.
+     </para>
+    </sect2>
+
+    <sect2 id="getting-started.pitfalls.memory-management">
+     <title>Memory management</title>
+     <para>
+      All objects provided by the <link linkend="core">Core Window Management Support</link> are owned by libwnck and should not be referenced or unreferenced by the user. Those objects are tied to X resources, and it makes no sense to keep the objects alive when the X resources are gone; doing so could lead to errors. Therefore it is important that, when keeping in memory a pointer to such an object, the life of this object is tracked to make sure the pointer is always valid.
+     </para>
+    </sect2>
+
+    <sect2 id="getting-started.pitfalls.client-type">
+     <title>Source indication</title>
+     <para>
+      Window management actions that are performed with libwnck are generally implemented as requests to the window manager. In order to not disturb the workflow of the user, the window manager may choose to put restrictions on various requests sent from applications. However, if those requests represent direct actions from the user, then the window manager will obey them. To indicate that the requests are the result of actions from the user, the application should set the <ulink url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#sourceindication";>source indication</ulink> in the requests, as defined in the EWMH. The <link linkend="wnck-set-client-type"><function>wnck_set_client_type()</function></link> can be used to define the source indication.
+     </para>
+    </sect2>
+
+    <sect2 id="getting-started.pitfalls.gdk-init">
+     <title>GDK initialization</title>
+     <para>
+      Internally, libwnck uses GDK. This means that before any call to libwnck API, GDK needs to be initialized. This can be achieved with <function>gdk_init()</function>, or indirectly via <function>gtk_init()</function>.
+     </para>
+    </sect2>
+   </refsect1>
+
+   <refsect1 id="getting-started.examples">
+    <title>Examples</title>
+
+    <para id="getting-started.examples.force-update">
+     This first example is a small utility listing all windows on the current screen. As this is all done synchronously, without using a main event loop, we use <link linkend="wnck-screen-force-update"><function>wnck_screen_force_update()</function></link> to explicitly fetch the information needed for the <link linkend="WnckScreen"><type>WnckScreen</type></link> object.
+
+     <informalexample>
+      <programlisting language="c">
+       <xi:include href="example-force-update.c" parse="text"/>
+      </programlisting>
+     </informalexample>
+    </para>
+
+    <para id="getting-started.examples.lazy-initialization">
+     The second example is similar, except that we use a main event loop. We connect to the <link linkend="WnckScreen-window-opened"><function>"window-opened"</function></link> signal to print information about new <link linkend="WnckScreen"><type>WnckScreen</type></link> objects. Here, we use the fact that the <link linkend="WnckScreen-window-opened"><function>"window-opened"</function></link> signal is emitted for all existing windows during the lazy initialization of the <link linkend="WnckScreen"><type>WnckScreen</type></link> object, in order to achieve an output similar to the previous example. However, during the lazy initialization, the active window is not necessarily known yet and we cannot tell whether the opened window is the currently active one. We connect to the <link linkend="WnckScreen-active-window-changed"><function>"active-window-changed"</function></link> signal to determine the active window when this information becomes available.
+
+     <informalexample>
+      <programlisting language="c">
+       <xi:include href="example-lazy-initialization.c" parse="text"/>
+      </programlisting>
+     </informalexample>
+    </para>
+
+   </refsect1>
+
+  </part>
 
   <part id="core">
     <title>Libwnck Core Window Management Support</title>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]