aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKoen Kooi <koen@openembedded.org>2010-04-22 15:42:33 +0200
committerKoen Kooi <koen@openembedded.org>2010-04-22 15:43:57 +0200
commit770632552a15954d1873c7a93adc724d4956bea9 (patch)
tree802afe414569bee5b2ebc62ae09ab12e867408ec
parent4cd4219072482dcf9ca9e34451bb5feba5668c0e (diff)
downloadopenembedded-770632552a15954d1873c7a93adc724d4956bea9.tar.gz
liblauncher: add 0.3.8, disabled by default since it breaks API
-rw-r--r--recipes/netbook-launcher/liblauncher-0.3.8/0001-liblauncher-udpate-0.3.6-to-0.3.8-which-the-ubuntu-f.patch1902
-rw-r--r--recipes/netbook-launcher/liblauncher_0.3.8.bb18
2 files changed, 1920 insertions, 0 deletions
diff --git a/recipes/netbook-launcher/liblauncher-0.3.8/0001-liblauncher-udpate-0.3.6-to-0.3.8-which-the-ubuntu-f.patch b/recipes/netbook-launcher/liblauncher-0.3.8/0001-liblauncher-udpate-0.3.6-to-0.3.8-which-the-ubuntu-f.patch
new file mode 100644
index 0000000000..02743fff70
--- /dev/null
+++ b/recipes/netbook-launcher/liblauncher-0.3.8/0001-liblauncher-udpate-0.3.6-to-0.3.8-which-the-ubuntu-f.patch
@@ -0,0 +1,1902 @@
+From aa6fe8c9abab71cc584ac64faf983fd25bf7bd4f Mon Sep 17 00:00:00 2001
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Thu, 22 Apr 2010 15:20:32 +0200
+Subject: [PATCH] liblauncher: udpate 0.3.6 to 0.3.8, which the ubuntu folks don't have available as tarball
+
+---
+ Makefile.in | 17 +-
+ aclocal.m4 | 6 +-
+ build/Makefile.in | 6 +-
+ build/autotools/Makefile.in | 2 +-
+ compile | 6 +-
+ configure | 28 +-
+ configure.ac | 2 +-
+ launcher/Makefile.in | 2 +-
+ launcher/launcher-application.c | 676 ++++++++++++++++++++++-----------------
+ launcher/launcher-application.h | 26 +-
+ launcher/launcher-appman.c | 108 ++++---
+ launcher/launcher-appman.h | 22 +-
+ launcher/launcher-category.h | 26 +-
+ launcher/launcher-session.c | 209 ++++--------
+ launcher/launcher-session.h | 6 -
+ tests/Makefile.am | 4 +-
+ tests/Makefile.in | 6 +-
+ 17 files changed, 594 insertions(+), 558 deletions(-)
+
+diff --git a/Makefile.in b/Makefile.in
+index 144b494..ce59a43 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.11 from Makefile.am.
++# Makefile.in generated by automake 1.11.1 from Makefile.am.
+ # @configure_input@
+
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -368,7 +368,7 @@ uninstall-pkgconfigDATA:
+ # (which will cause the Makefiles to be regenerated when you run `make');
+ # (2) otherwise, pass the desired values on the `make' command line.
+ $(RECURSIVE_TARGETS):
+- @failcom='exit 1'; \
++ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+@@ -393,7 +393,7 @@ $(RECURSIVE_TARGETS):
+ fi; test -z "$$fail"
+
+ $(RECURSIVE_CLEAN_TARGETS):
+- @failcom='exit 1'; \
++ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+@@ -557,7 +557,8 @@ distdir: $(DISTFILES)
+ fi; \
+ done
+ -test -n "$(am__skip_mode_fix)" \
+- || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
++ || find "$(distdir)" -type d ! -perm -755 \
++ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+@@ -601,17 +602,17 @@ dist dist-all: distdir
+ distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+- GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
++ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+- bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
++ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+- unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
++ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+- GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
++ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+diff --git a/aclocal.m4 b/aclocal.m4
+index 7db2b06..aa94962 100644
+--- a/aclocal.m4
++++ b/aclocal.m4
+@@ -1,4 +1,4 @@
+-# generated automatically by aclocal 1.11 -*- Autoconf -*-
++# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+ # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+ # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+@@ -192,7 +192,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
+ [am__api_version='1.11'
+ dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+ dnl require some minimum version. Point them to the right macro.
+-m4_if([$1], [1.11], [],
++m4_if([$1], [1.11.1], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+ ])
+
+@@ -208,7 +208,7 @@ m4_define([_AM_AUTOCONF_VERSION], [])
+ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+ # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+ AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+-[AM_AUTOMAKE_VERSION([1.11])dnl
++[AM_AUTOMAKE_VERSION([1.11.1])dnl
+ m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+diff --git a/build/Makefile.in b/build/Makefile.in
+index e35e7c8..671dc90 100644
+--- a/build/Makefile.in
++++ b/build/Makefile.in
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.11 from Makefile.am.
++# Makefile.in generated by automake 1.11.1 from Makefile.am.
+ # @configure_input@
+
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -271,7 +271,7 @@ clean-libtool:
+ # (which will cause the Makefiles to be regenerated when you run `make');
+ # (2) otherwise, pass the desired values on the `make' command line.
+ $(RECURSIVE_TARGETS):
+- @failcom='exit 1'; \
++ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+@@ -296,7 +296,7 @@ $(RECURSIVE_TARGETS):
+ fi; test -z "$$fail"
+
+ $(RECURSIVE_CLEAN_TARGETS):
+- @failcom='exit 1'; \
++ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+diff --git a/build/autotools/Makefile.in b/build/autotools/Makefile.in
+index b7ca0ef..53cec97 100644
+--- a/build/autotools/Makefile.in
++++ b/build/autotools/Makefile.in
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.11 from Makefile.am.
++# Makefile.in generated by automake 1.11.1 from Makefile.am.
+ # @configure_input@
+
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+diff --git a/compile b/compile
+index ec64c62..c0096a7 100755
+--- a/compile
++++ b/compile
+@@ -1,7 +1,7 @@
+ #! /bin/sh
+ # Wrapper for compilers which do not understand `-c -o'.
+
+-scriptversion=2009-04-28.21; # UTC
++scriptversion=2009-10-06.20; # UTC
+
+ # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software
+ # Foundation, Inc.
+@@ -124,9 +124,9 @@ trap "rmdir '$lockdir'; exit 1" 1 2 15
+ ret=$?
+
+ if test -f "$cofile"; then
+- mv "$cofile" "$ofile"
++ test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+ elif test -f "${cofile}bj"; then
+- mv "${cofile}bj" "$ofile"
++ test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+ fi
+
+ rmdir "$lockdir"
+diff --git a/configure b/configure
+index 11bb9cc..7db452e 100755
+--- a/configure
++++ b/configure
+@@ -1,6 +1,6 @@
+ #! /bin/sh
+ # Guess values for system-dependent variables and create Makefiles.
+-# Generated by GNU Autoconf 2.65 for liblauncher 0.3.6.
++# Generated by GNU Autoconf 2.65 for liblauncher 0.3.8.
+ #
+ # Report bugs to <https://bugs.launchpad.net/avani>.
+ #
+@@ -701,8 +701,8 @@ MAKEFLAGS=
+ # Identity of this package.
+ PACKAGE_NAME='liblauncher'
+ PACKAGE_TARNAME='liblauncher'
+-PACKAGE_VERSION='0.3.6'
+-PACKAGE_STRING='liblauncher 0.3.6'
++PACKAGE_VERSION='0.3.8'
++PACKAGE_STRING='liblauncher 0.3.8'
+ PACKAGE_BUGREPORT='https://bugs.launchpad.net/avani'
+ PACKAGE_URL=''
+
+@@ -1439,7 +1439,7 @@ if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+-\`configure' configures liblauncher 0.3.6 to adapt to many kinds of systems.
++\`configure' configures liblauncher 0.3.8 to adapt to many kinds of systems.
+
+ Usage: $0 [OPTION]... [VAR=VALUE]...
+
+@@ -1509,7 +1509,7 @@ fi
+
+ if test -n "$ac_init_help"; then
+ case $ac_init_help in
+- short | recursive ) echo "Configuration of liblauncher 0.3.6:";;
++ short | recursive ) echo "Configuration of liblauncher 0.3.8:";;
+ esac
+ cat <<\_ACEOF
+
+@@ -1616,7 +1616,7 @@ fi
+ test -n "$ac_init_help" && exit $ac_status
+ if $ac_init_version; then
+ cat <<\_ACEOF
+-liblauncher configure 0.3.6
++liblauncher configure 0.3.8
+ generated by GNU Autoconf 2.65
+
+ Copyright (C) 2009 Free Software Foundation, Inc.
+@@ -1987,7 +1987,7 @@ cat >config.log <<_ACEOF
+ This file contains any messages produced by compilers while
+ running configure, to aid debugging if configure makes a mistake.
+
+-It was created by liblauncher $as_me 0.3.6, which was
++It was created by liblauncher $as_me 0.3.8, which was
+ generated by GNU Autoconf 2.65. Invocation command line was
+
+ $ $0 $@
+@@ -2804,7 +2804,7 @@ fi
+
+ # Define the identity of the package.
+ PACKAGE='liblauncher'
+- VERSION='0.3.6'
++ VERSION='0.3.8'
+
+
+ cat >>confdefs.h <<_ACEOF
+@@ -2847,8 +2847,8 @@ am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+ LAUNCHER_MAJOR_VERSION=0
+ LAUNCHER_MINOR_VERSION=3
+-LAUNCHER_MICRO_VERSION=6
+-LAUNCHER_VERSION=0.3.6
++LAUNCHER_MICRO_VERSION=8
++LAUNCHER_VERSION=0.3.8
+
+
+
+@@ -2857,9 +2857,9 @@ LAUNCHER_VERSION=0.3.6
+
+
+
+-LAUNCHER_LT_CURRENT=306
++LAUNCHER_LT_CURRENT=308
+ LAUNCHER_LT_REV=0
+-LAUNCHER_LT_AGE=306
++LAUNCHER_LT_AGE=308
+ LAUNCHER_LT_VERSION="$LAUNCHER_LT_CURRENT:$LAUNCHER_LT_REV:$LAUNCHER_LT_AGE"
+ LAUNCHER_LT_LDFLAGS="-version-info $LAUNCHER_LT_VERSION"
+
+@@ -12041,7 +12041,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ # report actual input values of CONFIG_FILES etc. instead of their
+ # values after options handling.
+ ac_log="
+-This file was extended by liblauncher $as_me 0.3.6, which was
++This file was extended by liblauncher $as_me 0.3.8, which was
+ generated by GNU Autoconf 2.65. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+@@ -12107,7 +12107,7 @@ _ACEOF
+ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ ac_cs_version="\\
+-liblauncher config.status 0.3.6
++liblauncher config.status 0.3.8
+ configured by $0, generated by GNU Autoconf 2.65,
+ with options \\"\$ac_cs_config\\"
+
+diff --git a/configure.ac b/configure.ac
+index 7aa97ce..fd99da2 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -3,7 +3,7 @@
+ #
+ m4_define([launcher_major], [0])
+ m4_define([launcher_minor], [3])
+-m4_define([launcher_micro], [6])
++m4_define([launcher_micro], [8])
+
+ m4_define([launcher_api],
+ [launcher_major.launcher_minor])
+diff --git a/launcher/Makefile.in b/launcher/Makefile.in
+index 863a46e..b273ed6 100644
+--- a/launcher/Makefile.in
++++ b/launcher/Makefile.in
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.11 from Makefile.am.
++# Makefile.in generated by automake 1.11.1 from Makefile.am.
+ # @configure_input@
+
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+diff --git a/launcher/launcher-application.c b/launcher/launcher-application.c
+index fec440e..241abd2 100644
+--- a/launcher/launcher-application.c
++++ b/launcher/launcher-application.c
+@@ -34,6 +34,7 @@
+ #include "launcher-application.h"
+
+ #include <gio/gdesktopappinfo.h>
++#include <libwncksync/libwncksync.h>
+
+ #define TYPE_GS_LIST gs_list_get_type()
+
+@@ -68,13 +69,15 @@ enum
+ PROP_RUNNING,
+ PROP_FAVORITE,
+ PROP_FOCUSED,
+- PROP_WNCKAPPLICATIONS
+ };
+
+ enum
+ {
+ OPENED,
+ CLOSED,
++ FOCUS_CHANGED,
++ RUNNING_CHANGED,
++ URGENT_CHANGED,
+
+ LAST_SIGNAL
+ };
+@@ -93,26 +96,29 @@ struct _LauncherApplicationWindow
+
+ struct _LauncherApplicationPrivate
+ {
+- gchar *name;
+- gchar *exec;
+- gchar *icon_name;
+- gchar *comment;
+- gchar *desktop_file_path;
+- gchar *unique_string;
+- GSList *categories;
+- gboolean running;
+- gboolean favorite;
+- GSList *wnck_apps;
+- gboolean focused;
++ gchar *name;
++ gchar *exec;
++ gchar *icon_name;
++ gchar *comment;
++ gchar *desktop_file_path;
++ gchar *unique_string;
++ GSList *categories;
++ GSList *managed_windows;
++ gboolean running;
++ gboolean favorite;
++ gboolean focused;
+
+ WnckScreen *screen;
+- GHashTable *windows;
++ WnckWindow *primary_window;
+ };
+
+ static void
+-on_application_closed (WnckScreen *screen,
+- WnckApplication *app,
+- LauncherApplication *application);
++on_active_window_changed (WnckScreen *screen,
++ WnckWindow *previous,
++ LauncherApplication *app)
++{
++ launcher_application_ensure_state (app);
++}
+
+ static void
+ launcher_application_init (LauncherApplication *object)
+@@ -120,14 +126,11 @@ launcher_application_init (LauncherApplication *object)
+ LauncherApplicationPrivate *priv;
+
+ priv = object->priv = LAUNCHER_APPLICATION_GET_PRIVATE (object);
+- priv->running = FALSE;
+- priv->favorite = FALSE;
+
+ priv->screen = wnck_screen_get_default ();
+- g_signal_connect (priv->screen, "application-closed",
+- G_CALLBACK (on_application_closed), object);
+-
+- priv->windows = g_hash_table_new (g_direct_hash, g_direct_equal);
++
++ g_signal_connect (priv->screen, "active-window-changed",
++ G_CALLBACK (on_active_window_changed), object);
+ }
+
+ static void
+@@ -137,7 +140,6 @@ launcher_application_finalize (GObject *object)
+ LauncherApplicationPrivate *priv;
+
+ priv = LAUNCHER_APPLICATION_GET_PRIVATE (app);
+- g_hash_table_destroy (priv->windows);
+
+ G_OBJECT_CLASS (launcher_application_parent_class)->finalize (object);
+
+@@ -178,24 +180,16 @@ launcher_application_set_property (GObject *object,
+ case PROP_DESKTOP_FILE_PATH:
+ launcher_application_set_desktop_file(application,
+ g_value_dup_string(value));
++ launcher_application_update_windows (application);
+ break;
+ case PROP_UNIQUE_STRING:
+ break;
+ case PROP_CATEGORIES:
+ application->priv->categories = g_value_get_boxed(value);
+ break;
+- case PROP_RUNNING:
+- application->priv->running = g_value_get_boolean(value);
+- break;
+ case PROP_FAVORITE:
+ application->priv->favorite = g_value_get_boolean(value);
+ break;
+- case PROP_WNCKAPPLICATIONS:
+- application->priv->wnck_apps = g_value_get_boxed(value);
+- break;
+- case PROP_FOCUSED:
+- application->priv->focused = g_value_get_boolean (value);
+- break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+@@ -246,15 +240,8 @@ launcher_application_get_property (GObject *object,
+ case PROP_FAVORITE:
+ g_value_set_boolean(value, priv->favorite);
+ break;
+- case PROP_WNCKAPPLICATIONS:
+- g_value_set_object(value, priv->wnck_apps);
+- break;
+ case PROP_FOCUSED:
+- {
+- gboolean focused = FALSE;
+- focused = launcher_application_get_focused (application);
+- g_value_set_boolean (value, priv->focused);
+- }
++ g_value_set_boolean (value, priv->focused);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+@@ -264,14 +251,14 @@ launcher_application_get_property (GObject *object,
+
+ static void
+ launcher_application_opened (LauncherApplication *self,
+- WnckApplication *wnckapp)
++ WnckWindow *window)
+ {
+ /* TODO: Add default signal handler implementation here */
+ }
+
+ static void
+ launcher_application_closed (LauncherApplication *self,
+- WnckApplication *wnckapp)
++ WnckWindow *window)
+ {
+ /* TODO: Add default signal handler implementation here */
+ }
+@@ -369,22 +356,14 @@ launcher_application_class_init (LauncherApplicationClass *klass)
+ FALSE,
+ G_PARAM_READABLE));
+
+- g_object_class_install_property (object_class,
+- PROP_WNCKAPPLICATIONS,
+- g_param_spec_boxed ("wnckapps",
+- "wnckapps",
+- "a list of WnckApplication objects that this Application current has",
+- TYPE_GS_LIST,
+- G_PARAM_READABLE));
+-
+ application_signals[OPENED] =
+ g_signal_new ("opened",
+ G_OBJECT_CLASS_TYPE (klass),
+ 0,
+ G_STRUCT_OFFSET (LauncherApplicationClass, opened),
+ NULL, NULL,
+- g_cclosure_marshal_VOID__POINTER,
+- G_TYPE_NONE, 1, G_TYPE_POINTER
++ g_cclosure_marshal_VOID__OBJECT,
++ G_TYPE_NONE, 1, WNCK_TYPE_WINDOW
+ );
+
+ application_signals[CLOSED] =
+@@ -393,82 +372,44 @@ launcher_application_class_init (LauncherApplicationClass *klass)
+ 0,
+ G_STRUCT_OFFSET (LauncherApplicationClass, closed),
+ NULL, NULL,
+- g_cclosure_marshal_VOID__POINTER,
+- G_TYPE_NONE, 1, WNCK_TYPE_APPLICATION
++ g_cclosure_marshal_VOID__OBJECT,
++ G_TYPE_NONE, 1, WNCK_TYPE_WINDOW
+ );
+-}
+-
+-/*
+- * Private Methods
+- */
+-
+-
+-static void
+-on_application_closed (WnckScreen *screen,
+- WnckApplication *app,
+- LauncherApplication *application)
+-{
+- int wnck_pid = 0;
+- int app_pid = 1;
+- GSList *a;
+- WnckApplication *found_app = NULL;
+- /* when *any* application closes we do a quick check to see if its this one
+- * thus we need to make this check as quick and easy as possible
+- */
+- g_return_if_fail (LAUNCHER_IS_APPLICATION (application));
+- g_return_if_fail (WNCK_IS_APPLICATION (app));
+
+- /* we need to go though and check each wnckapp in this launcherapplication
+- * to see if the pid's match
+- */
+- wnck_pid = wnck_application_get_pid (app);
+- for (a = application->priv->wnck_apps; a; a = a->next)
+- {
+- WnckApplication *store_app = a->data;
+- app_pid = wnck_application_get_pid (store_app);
+- if (wnck_pid == app_pid)
+- {
+- found_app = store_app;
+- break;
+- }
+- }
+-
+- if (!found_app)
+- return;
+-
+- // we get here then we have the wnckapplication in our store
+- application->priv->wnck_apps = g_slist_remove(application->priv->wnck_apps,
+- found_app);
+- g_object_unref (found_app);
++ application_signals[FOCUS_CHANGED] =
++ g_signal_newv ("focus-changed",
++ G_OBJECT_CLASS_TYPE (klass),
++ 0,
++ NULL, NULL, NULL,
++ g_cclosure_marshal_VOID__VOID,
++ G_TYPE_NONE,
++ 0,
++ NULL);
+
+- // do we have any apps in our store? if so, we are running!
+- if (application->priv->wnck_apps != NULL)
+- {
+- g_object_set (G_OBJECT (application),
+- "running", TRUE,
+- NULL);
+- } else
+- {
+- g_object_set (G_OBJECT (application),
+- "running", FALSE,
+- NULL);
+- }
+-
+- g_object_set (G_OBJECT (application),
+- "focused", FALSE,
+- NULL);
+-
+- // we are closing apprently, lets emit a signal about that :-)
+- g_signal_emit (application, application_signals[CLOSED], 0, app);
++ application_signals[RUNNING_CHANGED] =
++ g_signal_newv ("running-changed",
++ G_OBJECT_CLASS_TYPE (klass),
++ 0,
++ NULL, NULL, NULL,
++ g_cclosure_marshal_VOID__VOID,
++ G_TYPE_NONE,
++ 0,
++ NULL);
++
++ application_signals[URGENT_CHANGED] =
++ g_signal_newv ("urgent-changed",
++ G_OBJECT_CLASS_TYPE (klass),
++ 0,
++ NULL, NULL, NULL,
++ g_cclosure_marshal_VOID__VOID,
++ G_TYPE_NONE,
++ 0,
++ NULL);
+ }
+
+-
+-
+ /*
+ * Constructors
+ */
+-
+-
+ LauncherApplication *
+ launcher_application_new (void)
+ {
+@@ -477,24 +418,43 @@ launcher_application_new (void)
+ application = g_object_new (LAUNCHER_TYPE_APPLICATION,
+ "running", FALSE,
+ NULL);
++
++
++
+ return application;
+ }
+
+ /**
+- * launcher_application_new_from_wnck_app:
+- * @app: A #WnckApplication object
++ * launcher_application_new_from_wnck_window:
++ * @window: A #WnckWindow object
+ *
+- * creates a new #LauncherApplication object based on information from @app
++ * creates a new #LauncherApplication object based on information from @window
+ */
+ LauncherApplication *
+-launcher_application_new_from_wnck_app (WnckApplication *app)
++launcher_application_new_from_wnck_window (WnckWindow *window)
+ {
+ LauncherApplication *application;
++ gchar *desktop_file;
++
++ g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL);
++
++ desktop_file = wncksync_desktop_item_for_xid (wnck_window_get_xid (window));
+
+ application = g_object_new (LAUNCHER_TYPE_APPLICATION,
+- "running", TRUE,
+- NULL);
+- launcher_application_add_wnckapp (application, app);
++ NULL);
++
++ /* give ourself a primary window to key off of if we have no desktop file to work with */
++ if (!desktop_file || !g_file_test (desktop_file, G_FILE_TEST_EXISTS))
++ {
++ application->priv->primary_window = window;
++ }
++ else
++ {
++ launcher_application_set_desktop_file (application, desktop_file);
++ }
++
++ launcher_application_update_windows (application);
++
+ return application;
+ }
+
+@@ -514,9 +474,10 @@ launcher_application_new_from_desktop_file (const gchar *desktop_file)
+ /* we can now make our application */
+ application = g_object_new (LAUNCHER_TYPE_APPLICATION,
+ "desktop_file_path", desktop_file,
+- "running", FALSE,
+ NULL);
+
++ launcher_application_update_windows (application);
++
+ return application;
+ }
+
+@@ -595,6 +556,20 @@ launcher_application_get_unique_string (LauncherApplication *application)
+ return application->priv->unique_string;
+ }
+
++gboolean
++launcher_application_owns_window (LauncherApplication *application,
++ WnckWindow *window)
++{
++ LauncherApplicationPrivate *priv;
++
++ g_return_val_if_fail (LAUNCHER_IS_APPLICATION (application), FALSE);
++ g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE);
++
++ priv = application->priv;
++
++ return g_slist_find (priv->managed_windows, window) != NULL;
++}
++
+ /**
+ * launcher_application_get_wnckapp:
+ * @app: a #LauncherApplication
+@@ -604,53 +579,209 @@ launcher_application_get_unique_string (LauncherApplication *application)
+ * Returns: (transfer none): a #GSList containing #WnckApplications
+ */
+ GSList *
+-launcher_application_get_wnckapps (LauncherApplication *application)
++launcher_application_get_windows (LauncherApplication *application)
+ {
+- g_return_val_if_fail (application, NULL);
++ g_return_val_if_fail (LAUNCHER_IS_APPLICATION (application), NULL);
+
+- return application->priv->wnck_apps;
++ return application->priv->managed_windows;
++}
++
++gboolean
++launcher_application_get_urgent (LauncherApplication *application)
++{
++ LauncherApplicationPrivate *priv;
++ GSList *l = NULL;
++ WnckWindow *window;
++
++ g_return_val_if_fail (LAUNCHER_IS_APPLICATION (application), FALSE);
++
++ priv = application->priv;
++
++ for (l = priv->managed_windows; l; l = l->next)
++ {
++ window = l->data;
++
++ if (wnck_window_needs_attention (window))
++ return TRUE;
++ }
++ return FALSE;
+ }
+
+-/**
+- * launcher_application_add_wnckapp
+- * @application: a #LauncherApplication object
+- * @wnck_app: a #WnckApplication object
+- *
+- * This method will add @wnck_app to @application and associate it with
+- * the various signals @application has.
+- */
+ void
+-launcher_application_add_wnckapp (LauncherApplication *application,
+- WnckApplication *wnck_app)
++launcher_application_ensure_state (LauncherApplication *application)
+ {
+- GSList *a;
+- gint pid = 0;
+- g_return_if_fail (application);
+- g_return_if_fail (wnck_app);
+-
+- /* first i guess we need to check to make sure that
+- * this WnckApplication does not already exist in the list
+- * of wnckapplications
+- */
+- pid = wnck_application_get_pid (wnck_app);
+- for (a = application->priv->wnck_apps; a; a = a->next)
++ LauncherApplicationPrivate *priv;
++ WnckWindow *active_window;
++ GSList *l = NULL;
++ gboolean prev_focus, prev_running;
++
++ g_return_if_fail (LAUNCHER_IS_APPLICATION (application));
++
++ priv = application->priv;
++ prev_focus = priv->focused;
++ prev_running = priv->running;
++
++ active_window = wnck_screen_get_active_window (priv->screen);
++
++ if (priv->managed_windows)
++ {
++ priv->running = TRUE;
++ priv->focused = FALSE;
++
++ if (active_window)
++ {
++ for (l = priv->managed_windows; l; l = l->next)
++ {
++ if (active_window == l->data)
++ {
++ priv->focused = TRUE;
++ break;
++ }
++ }
++ }
++ }
++ else if (WNCK_IS_WINDOW (priv->primary_window))
++ {
++ priv->running = TRUE;
++ priv->focused = active_window == priv->primary_window;
++ }
++ else
++ {
++ priv->running = FALSE;
++ priv->focused = FALSE;
++ }
++
++ if (prev_focus != priv->focused)
++ {
++ g_signal_emit (application, application_signals[FOCUS_CHANGED], 0);
++ }
++ if (prev_running != priv->running)
++ {
++ g_signal_emit (application, application_signals[RUNNING_CHANGED], 0);
++ }
++}
++
++
++void on_window_state_changed (WnckWindow *window,
++ WnckWindowState change_mask,
++ WnckWindowState new_state,
++ LauncherApplication *application)
++{
++ if (change_mask & WNCK_WINDOW_STATE_URGENT)
+ {
+- WnckApplication *app = a->data;
+- if (wnck_application_get_pid (app) == pid)
+- return;
++ g_signal_emit (application, application_signals[URGENT_CHANGED], 0);
+ }
++}
+
+- application->priv->wnck_apps = g_slist_append(application->priv->wnck_apps,
+- wnck_app);
+- g_object_ref(wnck_app);
++void
++connect_window_events (LauncherApplication *application)
++{
++ LauncherApplicationPrivate *priv;
++ GSList *l = NULL;
++ WnckWindow *window;
++
++ g_return_if_fail (LAUNCHER_IS_APPLICATION (application));
+
+- // we emit the opened signal here
+- g_signal_emit (application, application_signals[OPENED], 0, wnck_app);
++ priv = application->priv;
+
+- g_object_set (G_OBJECT (application),
+- "running", TRUE,
+- NULL);
++ for (l = priv->managed_windows; l; l = l->next)
++ {
++ window = l->data;
++ g_signal_connect (window, "state-changed",
++ G_CALLBACK (on_window_state_changed), application);
++ }
++}
+
++void disconnect_window_events (LauncherApplication *application)
++{
++ LauncherApplicationPrivate *priv;
++ GSList *l = NULL;
++ WnckWindow *window;
++
++ g_return_if_fail (LAUNCHER_IS_APPLICATION (application));
++
++ priv = application->priv;
++
++ for (l = priv->managed_windows; l; l = l->next)
++ {
++ window = l->data;
++ g_signal_handlers_disconnect_by_func (window,
++ G_CALLBACK (on_window_state_changed),
++ application);
++ }
++}
++
++void
++launcher_application_update_windows (LauncherApplication *application)
++{
++ LauncherApplicationPrivate *priv;
++ GArray *xids;
++ GSList *new_windows = NULL, *l = NULL;
++ WnckWindow *window;
++ int i;
++ guint32 xid;
++
++ g_return_if_fail (LAUNCHER_IS_APPLICATION (application));
++
++ priv = application->priv;
++
++ if (priv->primary_window)
++ {
++ if (!priv->managed_windows)
++ priv->managed_windows = g_slist_prepend (priv->managed_windows, priv->primary_window);
++ return;
++ }
++
++ xids = wncksync_xids_for_desktop_file (priv->desktop_file_path);
++
++ for (i = 0; i < xids->len; i++)
++ {
++ xid = g_array_index (xids, guint32, i);
++ window = wnck_window_get (xid);
++
++ if (!WNCK_IS_WINDOW (window) || wnck_window_is_skip_tasklist (window))
++ {
++ continue;
++ }
++ new_windows = g_slist_prepend (new_windows, window);
++ }
++
++
++ if (new_windows && priv->managed_windows)
++ {
++ if (g_slist_length (new_windows) > g_slist_length (priv->managed_windows))
++ {
++ for (l = new_windows; l; l = l->next)
++ {
++ if (g_slist_find (priv->managed_windows, l->data))
++ continue;
++ g_signal_emit (application, application_signals[OPENED], 0, l->data);
++ break;
++ }
++ }
++ else if (g_slist_length (new_windows) < g_slist_length (priv->managed_windows))
++ {
++ for (l = priv->managed_windows; l; l = l->next)
++ {
++ if (g_slist_find (new_windows, l->data))
++ continue;
++ g_signal_emit (application, application_signals[CLOSED], 0, l->data);
++ break;
++ }
++ }
++ }
++
++ if (priv->managed_windows)
++ {
++ disconnect_window_events (application);
++ g_slist_free (priv->managed_windows);
++ }
++ priv->managed_windows = new_windows;
++ connect_window_events (application);
++
++ launcher_application_ensure_state (application);
++
++ g_array_free (xids, TRUE);
+ }
+
+ /**
+@@ -746,7 +877,7 @@ void
+ launcher_application_set_desktop_file (LauncherApplication *application,
+ gchar *desktop_file)
+ {
+- GKeyFile *desktop_keyfile;
++ GKeyFile *desktop_keyfile;
+ GError *error = NULL;
+ gchar *name = NULL;
+ gchar *exec = NULL;
+@@ -884,149 +1015,110 @@ launcher_application_get_focused (LauncherApplication *application)
+ }
+
+ /**
+- * launcher_application_set_focused
+- * @application: A #LauncherApplication
+- * @window: A #WnckWindow
+- *
+- * provides a mechanism to set @application as focused by providing it the
+- * focused @window (or null), this does not focus said @window - passing null
+- * will not use the window tracking feature
++ * launcher_application_show
++ * @application: a #LauncherApplication
++ *
++ * this method will focus the latest un-minimized window this @application has
++ * all this @application's windows are minimized then this method will
++ * unminimize them all
+ */
+-
+ void
+-launcher_application_set_focused (LauncherApplication *application,
+- WnckWindow *window)
++launcher_application_show (LauncherApplication *application)
+ {
+- g_return_if_fail (application);
+- LauncherApplicationWindow *founditem;
+- GTimeVal timeval;
+-
+- g_get_current_time (&timeval);
++ LauncherApplicationPrivate *priv;
++ WnckWindow *best = NULL;
++ WnckWorkspace *workspace;
++ GSList *j;
++ GList *l;
++ GList *stack;
++
++ g_return_if_fail (LAUNCHER_IS_APPLICATION (application));
++
++ priv = application->priv;
++ workspace = wnck_screen_get_active_workspace (priv->screen);
++ stack = wnck_screen_get_windows_stacked (priv->screen);
+
+- if (window == NULL)
++ for (l = stack; l; l = l->next)
+ {
+- g_object_set (G_OBJECT (application),
+- "focused", TRUE,
+- NULL);
+- return;
++ j = g_slist_find (priv->managed_windows, l->data);
++ if (j)
++ {
++ best = j->data;
++ }
+ }
+-
+- founditem = g_hash_table_lookup (application->priv->windows,
+- window);
+-
+- if (founditem)
+- {
+- founditem->timestamp.tv_sec = timeval.tv_sec;
+- founditem->timestamp.tv_usec = timeval.tv_usec;
+- }
+- else
+- {
+- founditem = g_slice_new (LauncherApplicationWindow);
+- founditem->window = window;
+- founditem->timestamp.tv_sec = timeval.tv_sec;
+- founditem->timestamp.tv_usec = timeval.tv_usec;
+- g_hash_table_insert (application->priv->windows, window, founditem);
+- }
+-
+- g_object_set (G_OBJECT (application),
+- "focused", TRUE,
+- NULL);
++
++ if (best)
++ wnck_window_activate (best, gtk_get_current_event_time ());
+ }
+
+-WnckWindow *
+-get_latest_window(LauncherApplication *app)
++void
++launcher_application_minimize (LauncherApplication *application)
+ {
+- // attempts to find the last focused wnckwindow
+- WnckWindow *founditem = NULL;
+- GTimeVal best_time;
+- GHashTableIter iter;
+- gpointer key, value;
+-
+- best_time.tv_sec = 0;
+- best_time.tv_usec = 0;
+-
+- g_hash_table_iter_init (&iter, app->priv->windows);
+- while (g_hash_table_iter_next (&iter, &key, &value))
++ LauncherApplicationPrivate *priv;
++ WnckWindow *window;
++ GSList *l;
++
++ g_return_if_fail (LAUNCHER_IS_APPLICATION (application));
++
++ priv = application->priv;
++
++ for (l = priv->managed_windows; l; l = l->next)
+ {
+- LauncherApplicationWindow *appwin = (LauncherApplicationWindow *)value;
+- if (WNCK_IS_WINDOW (appwin->window))
+- {
+- WnckWindowType type = wnck_window_get_window_type (appwin->window);
+-
+- if (type == WNCK_WINDOW_DESKTOP ||
+- type == WNCK_WINDOW_DOCK ||
+- type == WNCK_WINDOW_TOOLBAR ||
+- type == WNCK_WINDOW_MENU ||
+- type == WNCK_WINDOW_SPLASHSCREEN)
+- {
+- continue;
+- }
+- if (appwin->timestamp.tv_sec > best_time.tv_sec)
+- {
+- if (appwin->timestamp.tv_usec > best_time.tv_usec)
+- {
+- best_time.tv_sec = appwin->timestamp.tv_sec;
+- best_time.tv_usec = appwin->timestamp.tv_usec;
+- founditem = appwin->window;
+- }
+- }
+- }
+- else
+- {
+- // our window no longer exists, remove it from the table
+- g_hash_table_remove (app->priv->windows, key);
+- }
++ window = l->data;
++
++ if (!WNCK_IS_WINDOW (window) || wnck_window_is_minimized (window))
++ continue;
++
++ wnck_window_minimize (window);
+ }
+-
+- return founditem;
+ }
+
+-
+-/**
+- * launcher_application_show
+- * @application: a #LauncherApplication
+- *
+- * this method will focus the latest un-minimized window this @application has
+- * all this @application's windows are minimized then this method will
+- * unminimize them all
+- */
+-void
+-launcher_application_show (LauncherApplication *application)
++gboolean
++launcher_application_has_minimized (LauncherApplication *application)
+ {
+- g_return_if_fail (application);
+- g_return_if_fail (application->priv->wnck_apps);
+-
+- /* FIXME
+- * for now i am just grabbing the first wnckwindow we find thats not
+- * minimized, really we need to track what windows are focused so we know
+- * the last focused window
+- */
+-
+- GSList *a;
+- GList *w;
+- WnckWindow *found_window = NULL;
+-
+- // get the last focused window
+- found_window = get_latest_window (application);
+-
+- if (found_window)
+- /* just show this window */
+- wnck_window_activate (found_window, gtk_get_current_event_time ());
+- else
++ LauncherApplicationPrivate *priv;
++ WnckWindow *window;
++ GSList *l;
++
++ g_return_val_if_fail (LAUNCHER_IS_APPLICATION (application), FALSE);
++
++ priv = application->priv;
++
++ for (l = priv->managed_windows; l; l = l->next)
+ {
+- /* either there were no windows or all windows were minimized, so
+- * unminimize them
+- */
+- for (a = application->priv->wnck_apps; a; a = a->next)
+- {
+- WnckApplication *app = a->data;
+-
+- for (w = wnck_application_get_windows (app); w; w = w->next)
+- {
+- WnckWindow *window = w->data;
+- wnck_window_activate (window, gtk_get_current_event_time ());
+- }
+- }
++ window = l->data;
++
++ if (!WNCK_IS_WINDOW (window))
++ continue;
++
++ if (wnck_window_is_minimized (window))
++ return TRUE;
+ }
++ return FALSE;
+ }
++
++void
++launcher_application_restore (LauncherApplication *application)
++{
++ LauncherApplicationPrivate *priv;
++ WnckWindow *window;
++ WnckWorkspace *workspace;
++ GSList *l;
++
++ g_return_if_fail (LAUNCHER_IS_APPLICATION (application));
++
++ priv = application->priv;
++ workspace = wnck_screen_get_active_workspace (priv->screen);
+
++
++ for (l = priv->managed_windows; l; l = l->next)
++ {
++ window = l->data;
++
++ if (!WNCK_IS_WINDOW (window) ||
++ !wnck_window_is_minimized (window))
++ continue;
++
++ wnck_window_unminimize (window, gtk_get_current_event_time ());
++ }
++}
+diff --git a/launcher/launcher-application.h b/launcher/launcher-application.h
+index 6290a1a..6b4f532 100644
+--- a/launcher/launcher-application.h
++++ b/launcher/launcher-application.h
+@@ -54,8 +54,8 @@ struct _LauncherApplicationClass
+ GObjectClass parent_class;
+
+ /* Signals */
+- void(* opened) (LauncherApplication *self, WnckApplication *wnckapp);
+- void(* closed) (LauncherApplication *self, WnckApplication *wnckapp);
++ void(* opened) (LauncherApplication *self, WnckWindow *wnckwindow);
++ void(* closed) (LauncherApplication *self, WnckWindow *wnckwindow);
+ };
+
+
+@@ -71,16 +71,21 @@ GType launcher_application_get_type (void) G_GNUC_CONST;
+
+ LauncherApplication * launcher_application_new (void);
+ LauncherApplication * launcher_application_new_from_desktop_file (const gchar *desktop_file);
+-LauncherApplication * launcher_application_new_from_wnck_app (WnckApplication *app);
++LauncherApplication * launcher_application_new_from_wnck_window (WnckWindow *window);
+
+ gboolean launcher_application_launch (LauncherApplication *application,
+ GError **error);
+
+ const gchar * launcher_application_get_unique_string (LauncherApplication *application);
+
+-GSList * launcher_application_get_wnckapps (LauncherApplication *application);
+-void launcher_application_add_wnckapp (LauncherApplication *application,
+- WnckApplication *wnck_app);
++GSList * launcher_application_get_windows (LauncherApplication *application);
++
++gboolean launcher_application_owns_window (LauncherApplication *application,
++ WnckWindow *window);
++
++void launcher_application_update_windows (LauncherApplication *application);
++
++void launcher_application_ensure_state (LauncherApplication *application);
+
+ const gchar * launcher_application_get_name (LauncherApplication *application);
+
+@@ -93,6 +98,8 @@ const gchar * launcher_application_get_exec_string (LauncherApplication *appl
+ const gchar * launcher_application_get_desktop_file (LauncherApplication *application);
+ void launcher_application_set_desktop_file (LauncherApplication *application,
+ gchar *desktop_file);
++
++gboolean launcher_application_get_urgent (LauncherApplication *application);
+
+ const gchar * launcher_application_get_unique_string (LauncherApplication *application);
+
+@@ -103,11 +110,14 @@ gboolean launcher_application_get_favorite (LauncherApplication *appl
+ GSList * launcher_application_get_categories (LauncherApplication *application);
+
+ gboolean launcher_application_get_focused (LauncherApplication *application);
+-void launcher_application_set_focused (LauncherApplication *application,
+- WnckWindow *window);
+
+ void launcher_application_show (LauncherApplication *application);
+
++void launcher_application_minimize (LauncherApplication *application);
++gboolean launcher_application_has_minimized (LauncherApplication *application);
++
++void launcher_application_restore (LauncherApplication *application);
++
+ G_END_DECLS
+
+ #endif /* _LAUNCHER_APPLICATION_H_ */
+diff --git a/launcher/launcher-appman.c b/launcher/launcher-appman.c
+index 9715b62..2787390 100644
+--- a/launcher/launcher-appman.c
++++ b/launcher/launcher-appman.c
+@@ -38,7 +38,6 @@ LAUNCHER_TYPE_APPMAN, LauncherAppmanPrivate))
+
+ struct _LauncherAppmanPrivate
+ {
+- GHashTable *app_lookup;
+ GSequence *app_list;
+ };
+
+@@ -55,7 +54,6 @@ launcher_appman_finalize (GObject *appman)
+ /* we assume that the application is shutting down and no longer needs the
+ * app cache
+ */
+- g_hash_table_destroy(priv->app_lookup);
+ g_sequence_free(priv->app_list);
+
+ G_OBJECT_CLASS (launcher_appman_parent_class)->finalize (appman);
+@@ -67,8 +65,6 @@ launcher_appman_init (LauncherAppman *appman)
+ LauncherAppmanPrivate *priv;
+
+ priv = appman->priv = LAUNCHER_APPMAN_GET_PRIVATE (appman);
+- /* FIXME - replace with g_hash_table_new_full */
+- priv->app_lookup = g_hash_table_new(g_str_hash, g_str_equal);
+ /* FIXME - add GDestroyNotify peramater */
+ priv->app_list = g_sequence_new(NULL);
+ }
+@@ -82,6 +78,18 @@ launcher_appman_class_init (LauncherAppmanClass *klass)
+ g_type_class_add_private (object_class, sizeof (LauncherAppmanPrivate));
+ }
+
++static void
++launcher_appman_add_application (LauncherAppman *appman,
++ LauncherApplication *application)
++{
++ LauncherAppmanPrivate *priv;
++
++ g_return_if_fail (LAUNCHER_IS_APPMAN (appman));
++ g_return_if_fail (LAUNCHER_IS_APPLICATION (application));
++
++ priv = appman->priv;
++ g_sequence_append (priv->app_list, application);
++}
+ /*
+ * Public methods
+ */
+@@ -120,33 +128,34 @@ LauncherApplication *
+ launcher_appman_get_application_for_desktop_file (LauncherAppman *appman,
+ const gchar *desktop)
+ {
+- LauncherApplication *found_app;
+-
++ LauncherAppmanPrivate * priv;
++ LauncherApplication * app;
++ const gchar * app_desktop_file;
++ GSequenceIter * iter;
++
+ g_return_val_if_fail (LAUNCHER_IS_APPMAN (appman), NULL);
+-
+- /* try and find the application in our cache */
+- found_app = g_hash_table_lookup (appman->priv->app_lookup, desktop);
+-
+- if (!found_app)
++
++ priv = appman->priv;
++
++ for (iter = g_sequence_get_begin_iter (priv->app_list);
++ !g_sequence_iter_is_end (iter);
++ iter = g_sequence_iter_next (iter))
+ {
+- /* we don't have this app in the cache yet, we need to generate it first
+- */
+- found_app = launcher_application_new_from_desktop_file (desktop);
+- if (found_app != NULL)
+- {
+- //add our app to the hash table
+- g_sequence_append (appman->priv->app_list, found_app);
+- g_hash_table_insert (appman->priv->app_lookup,
+- g_strdup (desktop),
+- found_app);
+-
+- } else {
+- // if we get here, there is a problem with the desktop file
+- g_critical("Could not create desktop file from %s", desktop);
+- }
++ app = g_sequence_get (iter);
++
++ if (!LAUNCHER_IS_APPLICATION (app))
++ continue;
++
++ app_desktop_file = launcher_application_get_desktop_file (app);
++
++ if (g_strcmp0 (app_desktop_file, desktop) == 0)
++ return app;
+ }
+-
+- return found_app;
++
++ app = launcher_application_new_from_desktop_file (desktop);
++ launcher_appman_add_application (appman, app);
++
++ return app;
+ }
+
+ /**
+@@ -160,37 +169,37 @@ launcher_appman_get_application_for_desktop_file (LauncherAppman *appman,
+ * Returns: A LauncherApplication object or NULL
+ */
+ LauncherApplication *
+-launcher_appman_get_application_for_wnck_app (LauncherAppman *appman,
+- WnckApplication *wnck_app)
++launcher_appman_get_application_for_wnck_window (LauncherAppman *appman,
++ WnckWindow *wnck_window)
+ {
+- LauncherApplication * found_app;
+- const gchar * wnck_name;
++ LauncherAppmanPrivate * priv;
++ LauncherApplication * app;
++ GSequenceIter * iter;
+
+ g_return_val_if_fail (LAUNCHER_IS_APPMAN (appman), NULL);
+- g_return_val_if_fail (WNCK_IS_APPLICATION (wnck_app), NULL);
++ g_return_val_if_fail (WNCK_IS_WINDOW (wnck_window), NULL);
+ // we need this method because of complications todo with sometimes not having
+ // a desktop file available
+
+- wnck_name = wnck_application_get_name (wnck_app);
++ priv = appman->priv;
+
+- found_app = g_hash_table_lookup (appman->priv->app_lookup, wnck_name);
+- if (!found_app)
++ for (iter = g_sequence_get_begin_iter (priv->app_list);
++ !g_sequence_iter_is_end (iter);
++ iter = g_sequence_iter_next (iter))
+ {
+- /* we don't have an app with this name in the cache yet, so generate a new
+- * one, this app basically has no info though
+- */
+- found_app = launcher_application_new_from_wnck_app (wnck_app);
+- if (found_app != NULL)
+- {
+- //add our app to the hash table
+- g_sequence_append (appman->priv->app_list, found_app);
+- g_hash_table_insert (appman->priv->app_lookup,
+- g_strdup (wnck_name),
+- found_app);
+- }
++ app = g_sequence_get (iter);
++
++ if (!LAUNCHER_IS_APPLICATION (app))
++ continue;
++
++ if (launcher_application_owns_window (app, wnck_window))
++ return app;
+ }
+
+- return found_app;
++ app = launcher_application_new_from_wnck_window (wnck_window);
++ launcher_appman_add_application (appman, app);
++
++ return app;
+ }
+
+
+@@ -210,3 +219,4 @@ launcher_appman_get_applications (LauncherAppman *appman)
+ g_return_val_if_fail (LAUNCHER_IS_APPMAN (appman), NULL);
+ return appman->priv->app_list;
+ }
++
+diff --git a/launcher/launcher-appman.h b/launcher/launcher-appman.h
+index 674a06e..e73af68 100644
+--- a/launcher/launcher-appman.h
++++ b/launcher/launcher-appman.h
+@@ -24,22 +24,24 @@
+ #include <glib.h>
+ #include <glib-object.h>
+
++#include <launcher/launcher-application.h>
++
+ G_BEGIN_DECLS
+
+ #define LAUNCHER_TYPE_APPMAN (launcher_appman_get_type ())
+
+ #define LAUNCHER_APPMAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ LAUNCHER_TYPE_APPMAN, LauncherAppman))
+-
++
+ #define LAUNCHER_APPMAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ LAUNCHER_TYPE_APPMAN, LauncherAppmanClass))
+-
++
+ #define LAUNCHER_IS_APPMAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ LAUNCHER_TYPE_APPMAN))
+-
++
+ #define LAUNCHER_IS_APPMAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ LAUNCHER_TYPE_APPMAN))
+-
++
+ #define LAUNCHER_APPMAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ LAUNCHER_TYPE_APPMAN, LauncherAppmanClass))
+
+@@ -56,7 +58,7 @@ struct _LauncherAppmanClass
+ struct _LauncherAppman
+ {
+ GObject parent_instance;
+-
++
+ /* private */
+ LauncherAppmanPrivate *priv;
+ };
+@@ -64,12 +66,12 @@ struct _LauncherAppman
+ GType launcher_appman_get_type (void) G_GNUC_CONST;
+ LauncherAppman * launcher_appman_get_default (void);
+
+-LauncherApplication * launcher_appman_get_application_for_desktop_file (LauncherAppman *appman,
++LauncherApplication * launcher_appman_get_application_for_desktop_file (LauncherAppman *appman,
+ const gchar *desktop);
+-
+-LauncherApplication * launcher_appman_get_application_for_wnck_app (LauncherAppman *appman,
+- WnckApplication *wnck_app);
+-
++
++LauncherApplication * launcher_appman_get_application_for_wnck_window (LauncherAppman *appman,
++ WnckWindow *wnck_window);
++
+ GSequence * launcher_appman_get_applications (LauncherAppman *appman);
+
+ G_END_DECLS
+diff --git a/launcher/launcher-category.h b/launcher/launcher-category.h
+index 6aa624e..fd1f342 100644
+--- a/launcher/launcher-category.h
++++ b/launcher/launcher-category.h
+@@ -23,26 +23,28 @@
+ #include <glib.h>
+ #include <glib-object.h>
+ #include <gdk/gdk.h>
+-#include "launcher-application.h"
++
++#include <launcher/launcher-application.h>
++
+ G_BEGIN_DECLS
+
+ #define LAUNCHER_TYPE_CATEGORY (launcher_category_get_type ())
+
+ #define LAUNCHER_CATEGORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ LAUNCHER_TYPE_CATEGORY, LauncherCategory))
+-
++
+ #define LAUNCHER_CATEGORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ LAUNCHER_TYPE_CATEGORY, LauncherCategoryClass))
+-
++
+ #define LAUNCHER_IS_CATEGORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ LAUNCHER_TYPE_CATEGORY))
+-
++
+ #define LAUNCHER_IS_CATEGORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ LAUNCHER_TYPE_CATEGORY))
+-
++
+ #define LAUNCHER_CATEGORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ LAUNCHER_TYPE_CATEGORY, LauncherCategoryClass))
+-
++
+ typedef struct _LauncherCategory LauncherCategory;
+ typedef struct _LauncherCategoryClass LauncherCategoryClass;
+ typedef struct _LauncherCategoryPrivate LauncherCategoryPrivate;
+@@ -62,20 +64,16 @@ struct _LauncherCategoryClass
+
+ /* Signals */
+ void(* removed) (LauncherCategory *self);
+- void(* application_added) (LauncherCategory *self,
++ void(* application_added) (LauncherCategory *self,
+ LauncherApplication *application);
+- void(* application_removed) (LauncherCategory *self,
++ void(* application_removed) (LauncherCategory *self,
+ LauncherApplication *application);
+ };
+
+-
+-
+-
+-
+ LauncherCategory * launcher_category_new (const gchar *name,
+ const gchar *comment,
+ const gchar *icon_name);
+-
++
+ const gchar * launcher_category_get_name (LauncherCategory *category);
+
+ const gchar * launcher_category_get_comment (LauncherCategory *category);
+@@ -84,7 +82,7 @@ const gchar * launcher_category_get_icon_name (LauncherCategory *category);
+
+ void launcher_category_add_application (LauncherCategory *category,
+ LauncherApplication *application);
+-
++
+ void launcher_category_remove_application (LauncherCategory *category,
+ LauncherApplication *application);
+
+diff --git a/launcher/launcher-session.c b/launcher/launcher-session.c
+index 80249b0..2993e5e 100644
+--- a/launcher/launcher-session.c
++++ b/launcher/launcher-session.c
+@@ -53,7 +53,6 @@ struct _LauncherSessionPrivate
+ {
+ /* Application variables */
+ WnckScreen *screen;
+- GSList *running_apps;
+ };
+
+ enum
+@@ -69,14 +68,13 @@ static guint _session_signals[LAST_SIGNAL] = { 0 };
+ static LauncherSession *launcher_session = NULL;
+
+ /* Forwards */
+-static void on_application_opened (WnckScreen *screen,
+- WnckApplication *app,
+- LauncherSession *session);
++static void on_window_opened (WnckScreen *screen,
++ WnckWindow *window,
++ LauncherSession *session);
+
+-static void
+-on_active_window_changed (WnckScreen *screen,
+- WnckWindow *previously_active_window,
+- LauncherSession *session);
++static void on_window_closed (WnckScreen *screen,
++ WnckWindow *window,
++ LauncherSession *session);
+
+ /* GObject Init */
+ static void
+@@ -87,12 +85,6 @@ launcher_session_finalize (GObject *session)
+ g_return_if_fail (LAUNCHER_IS_SESSION (session));
+ priv = LAUNCHER_SESSION (session)->priv;
+
+- if (priv->running_apps)
+- {
+- g_slist_foreach (priv->running_apps, (GFunc)g_object_unref, NULL);
+- g_slist_free (priv->running_apps);
+- priv->running_apps = NULL;
+- }
+ /* Note: We don't ref/unref priv->screen as-per-wnck-docs */
+ priv->screen = NULL;
+
+@@ -112,8 +104,8 @@ launcher_session_class_init (LauncherSessionClass *klass)
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (LauncherSessionClass, application_launching),
+ NULL, NULL,
+- g_cclosure_marshal_VOID__POINTER,
+- G_TYPE_NONE, 1, G_TYPE_POINTER);
++ g_cclosure_marshal_VOID__OBJECT,
++ G_TYPE_NONE, 1, LAUNCHER_TYPE_APPLICATION);
+
+ _session_signals[APP_OPENED] =
+ g_signal_new ("application-opened",
+@@ -121,8 +113,8 @@ launcher_session_class_init (LauncherSessionClass *klass)
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (LauncherSessionClass, application_opened),
+ NULL, NULL,
+- g_cclosure_marshal_VOID__POINTER,
+- G_TYPE_NONE, 1, G_TYPE_POINTER);
++ g_cclosure_marshal_VOID__OBJECT,
++ G_TYPE_NONE, 1, LAUNCHER_TYPE_APPLICATION);
+ g_type_class_add_private (obj_class, sizeof (LauncherSessionPrivate));
+ }
+
+@@ -137,11 +129,11 @@ launcher_session_init (LauncherSession *session)
+
+ /* Grab WnckScreen and connect to the important signals */
+ priv->screen = wnck_screen_get_default ();
+- g_signal_connect (priv->screen, "application-opened",
+- G_CALLBACK (on_application_opened), session);
+-
+- g_signal_connect (priv->screen, "active-window-changed",
+- G_CALLBACK (on_active_window_changed), session);
++ g_signal_connect (priv->screen, "window-opened",
++ G_CALLBACK (on_window_opened), session);
++
++ g_signal_connect (priv->screen, "window-closed",
++ G_CALLBACK (on_window_closed), session);
+ }
+
+ LauncherSession *
+@@ -163,139 +155,76 @@ launcher_session_get_default (void)
+ */
+
+ static void
+-on_application_opened (WnckScreen *screen,
+- WnckApplication *app,
+- LauncherSession *session)
++on_window_opened (WnckScreen *screen,
++ WnckWindow *window,
++ LauncherSession *session)
+ {
+- LauncherSessionPrivate *priv;
+- gchar *app_name = NULL;
+- gchar *res_name = NULL;
+- gchar *class_name = NULL;
+- LauncherApplication *bestmatch = NULL;
+- LauncherAppman *appman = NULL;
+- GList *windows, *w;
+-
+-
++ LauncherSessionPrivate *priv;
++ LauncherApplication *app;
++ LauncherAppman *appman;
++ GSequence *applications;
++ GSequenceIter *iter;
++ gboolean found = FALSE;
++
+ g_return_if_fail (LAUNCHER_IS_SESSION (session));
+- g_return_if_fail (WNCK_IS_APPLICATION (app));
++ g_return_if_fail (WNCK_IS_WINDOW (window));
++
++ if (wnck_window_is_skip_tasklist (window))
++ return;
++
+ priv = session->priv;
+
+ appman = launcher_appman_get_default ();
++ applications = launcher_appman_get_applications (appman);
+
+- /* first we want to attempt a match to a desktop file with libwncksync */
+- // grab a list of windows, loop though until we get a match
+- windows = wnck_application_get_windows (app);
+- for (w = windows; w; w = w->next)
++ for (iter = g_sequence_get_begin_iter (applications);
++ !g_sequence_iter_is_end (iter);
++ iter = g_sequence_iter_next (iter))
+ {
+- WnckWindow *window = w->data;
+- gchar *desktop_file = NULL;
++ app = g_sequence_get (iter);
++ launcher_application_update_windows (app);
+
+- desktop_file = wncksync_desktop_item_for_xid (wnck_window_get_xid (window));
+- //try the next item
+- if (!g_strcmp0("\0", desktop_file))
+- continue;
+- // create our LauncherApplication by looking in the LauncherAppman
+- bestmatch = launcher_appman_get_application_for_desktop_file (appman,
+- desktop_file);
+- if (bestmatch)
+- break;
+- }
+-
+- /* If we have a match, just ref it, otherwise create an app to represent the
+- * opened application */
+- if (bestmatch)
+- {
+- g_object_ref (bestmatch);
++ found = launcher_application_owns_window (app, window);
++
++ if (found)
++ {
++ if (g_slist_length (launcher_application_get_windows (app)) == 1)
++ g_signal_emit (session, _session_signals[APP_OPENED], 0, app);
++ break;
++ }
+ }
+- else
++
++ if (!found)
+ {
+- bestmatch = launcher_appman_get_application_for_wnck_app (appman,
+- app);
++ app = launcher_appman_get_application_for_wnck_window (appman, window);
++ g_signal_emit (session, _session_signals[APP_OPENED], 0, app);
+ }
+-
+- static GQuark quark;
+- if (!quark)
+- quark = g_quark_from_static_string ("launcher_app_qdata");
+-
+- launcher_application_add_wnckapp (bestmatch, app);
+- g_object_set_qdata (G_OBJECT (app), quark, bestmatch);
+-
+- /* Add to the list of running apps, set the data property for the
+- * WnckApplication class, so it's easy to locate when the application quits
+- * and finally emit the signal notifying of the opened application
+- */
+- priv->running_apps = g_slist_append (priv->running_apps, bestmatch);
+- g_object_set_data (G_OBJECT (app), LAUNCHERAPP_ID, bestmatch);
+- g_signal_emit (session, _session_signals[APP_OPENED], 0, bestmatch);
+-
+- g_free (app_name);
+- g_free (res_name);
+- g_free (class_name);
+ }
+
+ static void
+-on_active_window_changed (WnckScreen *screen,
+- WnckWindow *previously_active_window,
+- LauncherSession *session)
++on_window_closed (WnckScreen *screen,
++ WnckWindow *window,
++ LauncherSession *session)
+ {
+- g_return_if_fail (session);
+-
+- WnckWindow *active_window = NULL;
+- WnckApplication *new_wnckapp = NULL;
+- LauncherApplication *old_focused_app = NULL;
+- LauncherApplication *new_focused_app = NULL;
+-
+- static GQuark quark;
+- if (!quark)
+- quark = g_quark_from_static_string ("launcher_app_qdata");
+-
+- active_window = wnck_screen_get_active_window (screen);
+-
+- if (previously_active_window)
+- {
+- WnckApplication *old_wnckapp = NULL;
+- old_wnckapp = wnck_window_get_application (previously_active_window);
+- if (WNCK_IS_APPLICATION (old_wnckapp))
+- old_focused_app = g_object_get_qdata (G_OBJECT (old_wnckapp),
+- quark);
+-
+- if (old_focused_app)
+- g_object_set (G_OBJECT (old_focused_app),
+- "focused", FALSE,
+- NULL);
+- }
++ LauncherSessionPrivate *priv;
++ LauncherApplication *app;
++ LauncherAppman *appman;
++ GSequence *applications;
++ GSequenceIter *iter;
+
+-
++ g_return_if_fail (LAUNCHER_IS_SESSION (session));
++ g_return_if_fail (WNCK_IS_WINDOW (window));
+
+- if (active_window)
+- {
+- new_wnckapp = wnck_window_get_application (active_window);
+- new_focused_app = g_object_get_qdata (G_OBJECT (new_wnckapp),
+- quark);
+- g_assert (LAUNCHER_IS_APPLICATION (new_focused_app));
+-
+- launcher_application_set_focused (new_focused_app, active_window);
++ priv = session->priv;
++
++ appman = launcher_appman_get_default ();
++ applications = launcher_appman_get_applications (appman);
++
++ for (iter = g_sequence_get_begin_iter (applications);
++ !g_sequence_iter_is_end (iter);
++ iter = g_sequence_iter_next (iter))
++ {
++ app = g_sequence_get (iter);
++ launcher_application_update_windows (app);
+ }
+ }
+-
+-
+-/*
+- * Public Methods
+- */
+-
+-/**
+- * launcher_session_get_running_applications:
+- * @session: a #LauncherSession object
+- *
+- * This will produce a #GSList populated with currently running #LauncherApplication objects.
+- * This should be called after the mainloop has been started
+- * <emphasis>This list should not be modified as it is owned by #LauncherSession</emphasis>
+- *
+- * Returns: A #GSList containing LauncherApplication objects
+- */
+- GSList *
+-launcher_session_get_running_applications (LauncherSession *session)
+-{
+- g_return_val_if_fail (LAUNCHER_IS_SESSION (session), NULL);
+- return session->priv->running_apps;
+-}
+diff --git a/launcher/launcher-session.h b/launcher/launcher-session.h
+index 18a5dac..7f6ab24 100644
+--- a/launcher/launcher-session.h
++++ b/launcher/launcher-session.h
+@@ -80,12 +80,6 @@ GType launcher_session_get_type (void) G_GNUC_CONST;
+ */
+ LauncherSession * launcher_session_get_default (void);
+
+-/* Get's a list of LauncherApplication structs. _DO NOT_ modify this list,
+- * LauncherSession owns it. The LauncherApplication objects it contains can be
+- * ref'd/unref'd as desired (although not needed in normal use)
+- */
+-GSList * launcher_session_get_running_applications (LauncherSession *session);
+-
+ G_END_DECLS
+
+ #endif /* _HAVE_LAUNCHER_SESSION_H */
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index 77ba6e9..9f483e0 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -41,7 +41,7 @@ full-report:
+ check-local: test
+
+ # Xvfb server stuff (thanks Ted!)
+-XVFB = Xvfb -ac -noreset -screen 0 800x600x16 -extension RANDR -x GLX
++XVFB = Xvfb -ac -noreset -screen 0 800x600x16 -extension RANDR
+ XIDS = 101 102 103 104 105 106 107 197 199 211 223 227 293 307 308 309 310 311 \
+ 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 \
+ 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 \
+@@ -53,7 +53,7 @@ XVFB_START = \
+ && XID=`for id in $(XIDS) ; do test -e /tmp/.X$$id-lock || { echo $$id; exit 0; }; done; exit 1` \
+ && { ${XVFB} :$$XID -screen 0 800x600x16 -nolisten tcp -auth /dev/null >/dev/null 2>&1 & \
+ trap "kill -15 $$! " 0 HUP INT QUIT TRAP USR1 PIPE TERM ; } \
+- || { echo "Gtk+Tests:ERROR: Failed to start Xvfb environment for X11 target tests."; exit 1; } \
++ || { echo "Tests:ERROR: Failed to start Xvfb environment for X11 target tests."; exit 1; } \
+ && DISPLAY=:$$XID && export DISPLAY
+ # call as: $(XVFB_START) && someprogram
+
+diff --git a/tests/Makefile.in b/tests/Makefile.in
+index 406eef8..138432d 100644
+--- a/tests/Makefile.in
++++ b/tests/Makefile.in
+@@ -1,4 +1,4 @@
+-# Makefile.in generated by automake 1.11 from Makefile.am.
++# Makefile.in generated by automake 1.11.1 from Makefile.am.
+ # @configure_input@
+
+ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+@@ -227,7 +227,7 @@ test_liblauncher_CPPFLAGS = \
+ test_liblauncher_LDADD = $(top_builddir)/launcher/liblauncher-@LAUNCHER_MAJOR_VERSION@.@LAUNCHER_MINOR_VERSION@.la
+
+ # Xvfb server stuff (thanks Ted!)
+-XVFB = Xvfb -ac -noreset -screen 0 800x600x16 -extension RANDR -x GLX
++XVFB = Xvfb -ac -noreset -screen 0 800x600x16 -extension RANDR
+ XIDS = 101 102 103 104 105 106 107 197 199 211 223 227 293 307 308 309 310 311 \
+ 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 \
+ 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 \
+@@ -240,7 +240,7 @@ XVFB_START = \
+ && XID=`for id in $(XIDS) ; do test -e /tmp/.X$$id-lock || { echo $$id; exit 0; }; done; exit 1` \
+ && { ${XVFB} :$$XID -screen 0 800x600x16 -nolisten tcp -auth /dev/null >/dev/null 2>&1 & \
+ trap "kill -15 $$! " 0 HUP INT QUIT TRAP USR1 PIPE TERM ; } \
+- || { echo "Gtk+Tests:ERROR: Failed to start Xvfb environment for X11 target tests."; exit 1; } \
++ || { echo "Tests:ERROR: Failed to start Xvfb environment for X11 target tests."; exit 1; } \
+ && DISPLAY=:$$XID && export DISPLAY
+
+ EXTRA_DIST = firefox.desktop
+--
+1.6.6.1
+
diff --git a/recipes/netbook-launcher/liblauncher_0.3.8.bb b/recipes/netbook-launcher/liblauncher_0.3.8.bb
new file mode 100644
index 0000000000..76e42cc4e4
--- /dev/null
+++ b/recipes/netbook-launcher/liblauncher_0.3.8.bb
@@ -0,0 +1,18 @@
+DESCRIPTION = "A library to build launchers"
+LICENSE = "GPLv3,LGPLv2.1,LGPLv3"
+
+DEFAULT_PREFERENCE = "-1"
+
+DEPENDS = "glib-2.0 wncksync libwnck virtual/libx11 gconf gnome-menus"
+
+SRC_URI = "http://launchpad.net/liblauncher/0.3/0.3.6/+download/liblauncher-0.3.6.tar.gz;name=liblauncher \
+ file://0001-liblauncher-udpate-0.3.6-to-0.3.8-which-the-ubuntu-f.patch;patch=1 \
+"
+
+SRC_URI[liblauncher.md5sum] = "ba3ea890473f69000d1c843cee471471"
+SRC_URI[liblauncher.sha256sum] = "ec3223c6f46cf29d291ccd383527443ba725a0baca65e490307400af0ad30c04"
+
+inherit autotools
+
+S = "${WORKDIR}/${PN}-0.3.6"
+