From 770632552a15954d1873c7a93adc724d4956bea9 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 22 Apr 2010 15:42:33 +0200 Subject: liblauncher: add 0.3.8, disabled by default since it breaks API --- ...-udpate-0.3.6-to-0.3.8-which-the-ubuntu-f.patch | 1902 ++++++++++++++++++++ 1 file changed, 1902 insertions(+) create mode 100644 recipes/netbook-launcher/liblauncher-0.3.8/0001-liblauncher-udpate-0.3.6-to-0.3.8-which-the-ubuntu-f.patch (limited to 'recipes/netbook-launcher/liblauncher-0.3.8') 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 +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 . + # +@@ -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 ++#include + + #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 + #include + ++#include ++ + 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 + #include + #include +-#include "launcher-application.h" ++ ++#include ++ + 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 +- * This list should not be modified as it is owned by #LauncherSession +- * +- * 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 + -- cgit 1.2.3-korg