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