diff -Nru bamf-0.2.116/configure bamf-0.2.118/configure --- bamf-0.2.116/configure 2012-05-25 06:59:06.000000000 +0000 +++ bamf-0.2.118/configure 2012-05-25 06:59:07.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for bamf 0.2.116. +# Generated by GNU Autoconf 2.68 for bamf 0.2.118. # # Report bugs to . # @@ -570,8 +570,8 @@ # Identity of this package. PACKAGE_NAME='bamf' PACKAGE_TARNAME='bamf' -PACKAGE_VERSION='0.2.116' -PACKAGE_STRING='bamf 0.2.116' +PACKAGE_VERSION='0.2.118' +PACKAGE_STRING='bamf 0.2.118' PACKAGE_BUGREPORT='dx-team@canonical.com' PACKAGE_URL='' @@ -1377,7 +1377,7 @@ # 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 bamf 0.2.116 to adapt to many kinds of systems. +\`configure' configures bamf 0.2.118 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1447,7 +1447,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of bamf 0.2.116:";; + short | recursive ) echo "Configuration of bamf 0.2.118:";; esac cat <<\_ACEOF @@ -1587,7 +1587,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -bamf configure 0.2.116 +bamf configure 0.2.118 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1865,7 +1865,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by bamf $as_me 0.2.116, which was +It was created by bamf $as_me 0.2.118, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2686,7 +2686,7 @@ # Define the identity of the package. PACKAGE='bamf' - VERSION='0.2.116' + VERSION='0.2.118' cat >>confdefs.h <<_ACEOF @@ -15228,7 +15228,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by bamf $as_me 0.2.116, which was +This file was extended by bamf $as_me 0.2.118, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15294,7 +15294,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -bamf config.status 0.2.116 +bamf config.status 0.2.118 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff -Nru bamf-0.2.116/configure.in bamf-0.2.118/configure.in --- bamf-0.2.116/configure.in 2012-05-25 06:59:06.000000000 +0000 +++ bamf-0.2.118/configure.in 2012-05-25 06:59:07.000000000 +0000 @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.63]) -AC_INIT(bamf, 0.2.116, dx-team@canonical.com) +AC_INIT(bamf, 0.2.118, dx-team@canonical.com) AC_PREREQ(2.62) AC_CONFIG_SRCDIR(src/main.c) diff -Nru bamf-0.2.116/debian/changelog bamf-0.2.118/debian/changelog --- bamf-0.2.116/debian/changelog 2012-05-25 06:59:06.000000000 +0000 +++ bamf-0.2.118/debian/changelog 2012-05-25 06:59:07.000000000 +0000 @@ -1,8 +1,32 @@ -bamf (0.2.116-0ubuntu1~oneiric1) oneiric; urgency=low +bamf (0.2.118-0ubuntu1~oneiric1) oneiric; urgency=medium - * New upstream release + * Copied from quantal - -- Rico Tzschichholz Tue, 01 May 2012 13:23:31 +0200 + -- Rico Tzschichholz Fri, 25 May 2012 08:28:11 +0200 + +bamf (0.2.118-0ubuntu1) quantal; urgency=low + + [ Didier Roche ] + * New upstream release. (0.2.116) + - multiple instances or double icons of application detected on bamfdaemon + respawn (LP: #928912) + - unity confused with chrome/chromium web apps (LP: #692462) + - BamfView's dispose() method doesn't invoke the superclass' dispose() + (LP: #986888) + * debian/control: + - remove Multi-Arch: same for the -dbg package + (Closes: #669980, #658057) + + [ Alan Pope ] + * New upstream release. + - Unity crashed in bamf_application_on_window_removed (LP: #1000577) + - Locked smuxi launcher icon does not indicate smuxi running status + (LP: #999820) + - No launcher icon or Alt+Tab entry for Gimp windows (LP: #995916) + - the RunningApplicationsChanged signal is no longer emitted when an + application is closed since r460 (LP: #989551) + + -- Alan Pope Wed, 23 May 2012 09:10:08 +0100 bamf (0.2.114-0ubuntu1) precise-proposed; urgency=low diff -Nru bamf-0.2.116/debian/control bamf-0.2.118/debian/control --- bamf-0.2.116/debian/control 2012-05-25 06:59:06.000000000 +0000 +++ bamf-0.2.118/debian/control 2012-05-25 06:59:07.000000000 +0000 @@ -114,7 +114,6 @@ ${misc:Depends}, libbamf0 (= ${binary:Version}), libbamf3-0 (= ${binary:Version}), -Multi-Arch: same Description: Window matching library - debugging symbols bamf matches application windows to desktop files . diff -Nru bamf-0.2.116/doc/reference/libbamf/html/api-index-full.html bamf-0.2.118/doc/reference/libbamf/html/api-index-full.html --- bamf-0.2.116/doc/reference/libbamf/html/api-index-full.html 2012-04-26 09:20:52.000000000 +0000 +++ bamf-0.2.118/doc/reference/libbamf/html/api-index-full.html 2012-05-23 08:07:05.000000000 +0000 @@ -63,6 +63,10 @@
+bamf_application_get_cached_xids, function in bamf-application-private +
+
+
bamf_application_get_desktop_file, function in BamfApplication
@@ -121,6 +125,10 @@
+BamfFactoryViewType, enum in BamfFactory +
+
+
bamf_factory_app_for_file, function in BamfFactory
@@ -132,6 +140,14 @@ bamf_factory_view_for_path, function in BamfFactory
+
+bamf_factory_view_for_path_type, function in BamfFactory +
+
+
+bamf_factory_view_for_path_type_str, function in BamfFactory +
+

I

BamfIndicator, struct in BamfIndicator @@ -437,6 +453,10 @@
+bamf_view_reset_flags, function in bamf-view-private +
+
+
bamf_view_set_icon, function in bamf-view-private
diff -Nru bamf-0.2.116/doc/reference/libbamf/html/BamfFactory.html bamf-0.2.118/doc/reference/libbamf/html/BamfFactory.html --- bamf-0.2.116/doc/reference/libbamf/html/BamfFactory.html 2012-04-26 09:20:52.000000000 +0000 +++ bamf-0.2.118/doc/reference/libbamf/html/BamfFactory.html 2012-05-23 08:07:05.000000000 +0000 @@ -41,12 +41,19 @@

Synopsis

struct              BamfFactory;
 struct              BamfFactoryClass;
+enum                BamfFactoryViewType;
 BamfApplication *   bamf_factory_app_for_file           (BamfFactory *factory,
                                                          const char *path,
                                                          gboolean create);
 BamfFactory *       bamf_factory_get_default            (void);
 BamfView *          bamf_factory_view_for_path          (BamfFactory *factory,
                                                          const char *path);
+BamfView *          bamf_factory_view_for_path_type     (BamfFactory *factory,
+                                                         const char *path,
+                                                         BamfFactoryViewType type);
+BamfView *          bamf_factory_view_for_path_type_str (BamfFactory *factory,
+                                                         const char *path,
+                                                         const char *type);
 
@@ -82,6 +89,20 @@

+

enum BamfFactoryViewType

+
typedef enum {
+  BAMF_FACTORY_VIEW,
+  BAMF_FACTORY_WINDOW,
+  BAMF_FACTORY_APPLICATION,
+  BAMF_FACTORY_INDICATOR,
+  BAMF_FACTORY_NONE
+} BamfFactoryViewType;
+
+

+

+
+
+

bamf_factory_app_for_file ()

BamfApplication *   bamf_factory_app_for_file           (BamfFactory *factory,
                                                          const char *path,
@@ -104,6 +125,24 @@
 

+
+
+

bamf_factory_view_for_path_type ()

+
BamfView *          bamf_factory_view_for_path_type     (BamfFactory *factory,
+                                                         const char *path,
+                                                         BamfFactoryViewType type);
+

+

+
+
+
+

bamf_factory_view_for_path_type_str ()

+
BamfView *          bamf_factory_view_for_path_type_str (BamfFactory *factory,
+                                                         const char *path,
+                                                         const char *type);
+

+

+
BamfMatcher — The base class for all matchers diff -Nru bamf-0.2.116/doc/reference/libbamf/html/index.sgml bamf-0.2.118/doc/reference/libbamf/html/index.sgml --- bamf-0.2.116/doc/reference/libbamf/html/index.sgml 2012-04-26 09:20:52.000000000 +0000 +++ bamf-0.2.118/doc/reference/libbamf/html/index.sgml 2012-05-23 08:07:04.000000000 +0000 @@ -54,9 +54,12 @@ + + + diff -Nru bamf-0.2.116/doc/reference/libbamf/html/libbamf.devhelp2 bamf-0.2.118/doc/reference/libbamf/html/libbamf.devhelp2 --- bamf-0.2.116/doc/reference/libbamf/html/libbamf.devhelp2 2012-04-26 09:20:52.000000000 +0000 +++ bamf-0.2.118/doc/reference/libbamf/html/libbamf.devhelp2 2012-05-23 08:07:04.000000000 +0000 @@ -53,9 +53,12 @@ + + + diff -Nru bamf-0.2.116/doc/reference/libbamf/libbamf-sections.txt bamf-0.2.118/doc/reference/libbamf/libbamf-sections.txt --- bamf-0.2.116/doc/reference/libbamf/libbamf-sections.txt 2012-04-26 09:20:52.000000000 +0000 +++ bamf-0.2.118/doc/reference/libbamf/libbamf-sections.txt 2012-05-23 08:07:05.000000000 +0000 @@ -20,6 +20,11 @@
+bamf-application-private +bamf_application_get_cached_xids +
+ +
bamf-control BamfControl BamfControl @@ -45,9 +50,12 @@ BamfFactory BamfFactory BamfFactoryClass +BamfFactoryViewType bamf_factory_app_for_file bamf_factory_get_default bamf_factory_view_for_path +bamf_factory_view_for_path_type +bamf_factory_view_for_path_type_str BAMF_FACTORY BAMF_FACTORY_CLASS @@ -187,6 +195,7 @@ bamf-view-private bamf_view_get_path bamf_view_remote_ready +bamf_view_reset_flags bamf_view_set_icon bamf_view_set_name bamf_view_set_path diff -Nru bamf-0.2.116/doc/reference/libbamf/tmpl/bamf-application-private.sgml bamf-0.2.118/doc/reference/libbamf/tmpl/bamf-application-private.sgml --- bamf-0.2.116/doc/reference/libbamf/tmpl/bamf-application-private.sgml 1970-01-01 00:00:00.000000000 +0000 +++ bamf-0.2.118/doc/reference/libbamf/tmpl/bamf-application-private.sgml 2012-05-23 08:07:04.000000000 +0000 @@ -0,0 +1,33 @@ + +bamf-application-private + + + + + + + + + + + + + + + + + + + + + + + + + + + +@app: +@Returns: + + diff -Nru bamf-0.2.116/doc/reference/libbamf/tmpl/bamf-factory.sgml bamf-0.2.118/doc/reference/libbamf/tmpl/bamf-factory.sgml --- bamf-0.2.116/doc/reference/libbamf/tmpl/bamf-factory.sgml 2012-04-26 09:20:52.000000000 +0000 +++ bamf-0.2.118/doc/reference/libbamf/tmpl/bamf-factory.sgml 2012-05-23 08:07:04.000000000 +0000 @@ -35,6 +35,17 @@ @parent_class: + + + + + +@BAMF_FACTORY_VIEW: +@BAMF_FACTORY_WINDOW: +@BAMF_FACTORY_APPLICATION: +@BAMF_FACTORY_INDICATOR: +@BAMF_FACTORY_NONE: + @@ -65,3 +76,25 @@ @Returns: + + + + + +@factory: +@path: +@type: +@Returns: + + + + + + + +@factory: +@path: +@type: +@Returns: + + diff -Nru bamf-0.2.116/doc/reference/libbamf/tmpl/bamf-view-private.sgml bamf-0.2.118/doc/reference/libbamf/tmpl/bamf-view-private.sgml --- bamf-0.2.116/doc/reference/libbamf/tmpl/bamf-view-private.sgml 2012-04-26 09:20:52.000000000 +0000 +++ bamf-0.2.118/doc/reference/libbamf/tmpl/bamf-view-private.sgml 2012-05-23 08:07:04.000000000 +0000 @@ -40,6 +40,14 @@ @Returns: + + + + + +@view: + + diff -Nru bamf-0.2.116/lib/libbamf/bamf-application.c bamf-0.2.118/lib/libbamf/bamf-application.c --- bamf-0.2.116/lib/libbamf/bamf-application.c 2012-04-26 09:19:57.000000000 +0000 +++ bamf-0.2.118/lib/libbamf/bamf-application.c 2012-05-23 08:03:26.000000000 +0000 @@ -37,6 +37,7 @@ #include "bamf-application.h" #include "bamf-window.h" #include "bamf-factory.h" +#include "bamf-application-private.h" #include "bamf-view-private.h" #include @@ -66,6 +67,7 @@ DBusGProxy *proxy; gchar *application_type; gchar *desktop_file; + GList *cached_xids; int show_stubs; }; @@ -98,6 +100,12 @@ return NULL; } + if (file && file[0] == '\0') + { + g_free (file); + file = NULL; + } + priv->desktop_file = file; return file; } @@ -185,6 +193,7 @@ } } + g_list_free (children); return windows; } @@ -238,20 +247,77 @@ bamf_application_on_window_added (DBusGProxy *proxy, char *path, BamfApplication *self) { BamfView *view; + BamfFactory *factory; - view = bamf_factory_view_for_path (bamf_factory_get_default (), path); + g_return_if_fail (BAMF_IS_APPLICATION (self)); + + factory = bamf_factory_get_default (); + view = bamf_factory_view_for_path_type (factory, path, BAMF_FACTORY_WINDOW); + + if (BAMF_IS_WINDOW (view)) + { + guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view)); - g_signal_emit (G_OBJECT (self), application_signals[WINDOW_ADDED], 0, view); + if (!g_list_find (self->priv->cached_xids, GUINT_TO_POINTER (xid))) + { + self->priv->cached_xids = g_list_prepend (self->priv->cached_xids, GUINT_TO_POINTER (xid)); + } + + g_signal_emit (G_OBJECT (self), application_signals[WINDOW_ADDED], 0, view); + } } static void bamf_application_on_window_removed (DBusGProxy *proxy, char *path, BamfApplication *self) { BamfView *view; + BamfFactory *factory; + + g_return_if_fail (BAMF_IS_APPLICATION (self)); - view = bamf_factory_view_for_path (bamf_factory_get_default (), path); + factory = bamf_factory_get_default (); + view = bamf_factory_view_for_path_type (factory, path, BAMF_FACTORY_WINDOW); + + if (BAMF_IS_WINDOW (view)) + { + guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view)); + self->priv->cached_xids = g_list_remove (self->priv->cached_xids, GUINT_TO_POINTER (xid)); - g_signal_emit (G_OBJECT (self), application_signals[WINDOW_REMOVED], 0, view); + g_signal_emit (G_OBJECT (self), application_signals[WINDOW_REMOVED], 0, view); + } +} + +GList * +bamf_application_get_cached_xids (BamfApplication *self) +{ + g_return_val_if_fail (BAMF_IS_APPLICATION (self), NULL); + + return self->priv->cached_xids; +} + +static void +bamf_application_unset_proxy (BamfApplication* self) +{ + BamfApplicationPrivate *priv; + + g_return_if_fail (BAMF_IS_APPLICATION (self)); + priv = self->priv; + + if (!priv->proxy) + return; + + dbus_g_proxy_disconnect_signal (priv->proxy, + "WindowAdded", + (GCallback) bamf_application_on_window_added, + self); + + dbus_g_proxy_disconnect_signal (priv->proxy, + "WindowRemoved", + (GCallback) bamf_application_on_window_removed, + self); + + g_object_unref (priv->proxy); + priv->proxy = NULL; } static void @@ -275,22 +341,14 @@ priv->desktop_file = NULL; } - if (priv->proxy) + if (priv->cached_xids) { - dbus_g_proxy_disconnect_signal (priv->proxy, - "WindowAdded", - (GCallback) bamf_application_on_window_added, - self); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "WindowRemoved", - (GCallback) bamf_application_on_window_removed, - self); - - g_object_unref (priv->proxy); - priv->proxy = NULL; + g_list_free (priv->cached_xids); + priv->cached_xids = NULL; } + bamf_application_unset_proxy (self); + if (G_OBJECT_CLASS (bamf_application_parent_class)->dispose) G_OBJECT_CLASS (bamf_application_parent_class)->dispose (object); } @@ -304,6 +362,7 @@ self = BAMF_APPLICATION (view); priv = self->priv; + bamf_application_unset_proxy (self); priv->proxy = dbus_g_proxy_new_for_name (priv->connection, "org.ayatana.bamf", path, @@ -335,6 +394,26 @@ (GCallback) bamf_application_on_window_removed, self, NULL); + + GList *children, *l; + children = bamf_view_get_children (view); + + if (priv->cached_xids) + { + g_list_free (priv->cached_xids); + priv->cached_xids = NULL; + } + + for (l = children; l; l = l->next) + { + if (!BAMF_IS_WINDOW (l->data)) + continue; + + guint32 xid = bamf_window_get_xid (BAMF_WINDOW (l->data)); + priv->cached_xids = g_list_prepend (priv->cached_xids, GUINT_TO_POINTER (xid)); + } + + g_list_free (children); } static void diff -Nru bamf-0.2.116/lib/libbamf/bamf-application-private.h bamf-0.2.118/lib/libbamf/bamf-application-private.h --- bamf-0.2.116/lib/libbamf/bamf-application-private.h 1970-01-01 00:00:00.000000000 +0000 +++ bamf-0.2.118/lib/libbamf/bamf-application-private.h 2012-05-23 08:03:26.000000000 +0000 @@ -0,0 +1,30 @@ +/* + * bamf-application-private.h + * This file is part of BAMF + * + * Copyright (C) 2012 - Marco Trevisan (Treviño) + * + * BAMF is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * BAMF is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with BAMF; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef _BAMF_APPLICATION_PRIVATE_H_ +#define _BAMF_APPLICATION_PRIVATE_H_ + +#include + +GList *bamf_application_get_cached_xids (BamfApplication *app); + +#endif diff -Nru bamf-0.2.116/lib/libbamf/bamf-factory.c bamf-0.2.118/lib/libbamf/bamf-factory.c --- bamf-0.2.116/lib/libbamf/bamf-factory.c 2012-04-26 09:19:57.000000000 +0000 +++ bamf-0.2.118/lib/libbamf/bamf-factory.c 2012-05-23 08:03:26.000000000 +0000 @@ -39,6 +39,7 @@ #include "bamf-view-private.h" #include "bamf-window.h" #include "bamf-application.h" +#include "bamf-application-private.h" #include "bamf-indicator.h" #include @@ -159,68 +160,181 @@ return result; } +static +BamfFactoryViewType compute_factory_type_by_str (const char *type) +{ + BamfFactoryViewType factory_type = BAMF_FACTORY_NONE; + + if (type && type[0] != '\0') + { + if (g_strcmp0 (type, "window") == 0) + { + factory_type = BAMF_FACTORY_WINDOW; + } + else if (g_strcmp0 (type, "application") == 0) + { + factory_type = BAMF_FACTORY_APPLICATION; + } + else if (g_strcmp0 (type, "indicator") == 0) + { + factory_type = BAMF_FACTORY_INDICATOR; + } + else if (g_strcmp0 (type, "view") == 0) + { + factory_type = BAMF_FACTORY_VIEW; + } + } + + return factory_type; +} + BamfView * -bamf_factory_view_for_path (BamfFactory * factory, - const char * path) +bamf_factory_view_for_path (BamfFactory * factory, const char * path) +{ + return bamf_factory_view_for_path_type (factory, path, BAMF_FACTORY_NONE); +} + +BamfView * +bamf_factory_view_for_path_type_str (BamfFactory * factory, const char * path, + const char * type) +{ + g_return_val_if_fail (BAMF_IS_FACTORY (factory), NULL); + BamfFactoryViewType factory_type = compute_factory_type_by_str (type); + + return bamf_factory_view_for_path_type (factory, path, factory_type); +} + +BamfView * +bamf_factory_view_for_path_type (BamfFactory * factory, const char * path, + BamfFactoryViewType type) { GHashTable *views; BamfView *view; GList *l; - gchar *type; gboolean created = FALSE; g_return_val_if_fail (BAMF_IS_FACTORY (factory), NULL); - if (!path || strlen (path) == 0) + if (!path || path[0] == '\0') return NULL; views = factory->priv->views; - view = g_hash_table_lookup (views, path); if (BAMF_IS_VIEW (view)) return view; - - view = g_object_new (BAMF_TYPE_VIEW, NULL); - bamf_view_set_path (view, path); - type = g_strdup (bamf_view_get_view_type (view)); - g_object_unref (view); - - view = NULL; - if (g_strcmp0 (type, "application") == 0) - view = BAMF_VIEW (bamf_application_new (path)); - else if (g_strcmp0 (type, "window") == 0) - view = BAMF_VIEW (bamf_window_new (path)); - else if (g_strcmp0 (type, "indicator") == 0) - view = BAMF_VIEW (bamf_indicator_new (path)); - + + if (type == BAMF_FACTORY_NONE) + { + view = g_object_new (BAMF_TYPE_VIEW, NULL); + bamf_view_set_path (view, path); + type = compute_factory_type_by_str (bamf_view_get_view_type (view)); + g_object_unref (view); + view = NULL; + } + + switch (type) + { + case BAMF_FACTORY_VIEW: + view = g_object_new (BAMF_TYPE_VIEW, NULL); + break; + case BAMF_FACTORY_WINDOW: + view = BAMF_VIEW (bamf_window_new (path)); + break; + case BAMF_FACTORY_APPLICATION: + view = BAMF_VIEW (bamf_application_new (path)); + break; + case BAMF_FACTORY_INDICATOR: + view = BAMF_VIEW (bamf_indicator_new (path)); + break; + case BAMF_FACTORY_NONE: + view = NULL; + } + created = TRUE; - + BamfView *matched_view = NULL; + if (BAMF_IS_APPLICATION (view)) { /* handle case where a favorite exists and this matches it */ const char *local_desktop_file = bamf_application_get_desktop_file (BAMF_APPLICATION (view)); + GList *local_children = bamf_view_get_children (view); + for (l = factory->priv->local_views; l; l = l->next) { - /* remote ready views are already matched */ - if (bamf_view_remote_ready (BAMF_VIEW (l->data)) || !BAMF_IS_APPLICATION (l->data)) + if (!BAMF_IS_APPLICATION (l->data)) continue; - - const char *list_desktop_file = bamf_application_get_desktop_file (BAMF_APPLICATION (l->data)); - - if (g_strcmp0 (local_desktop_file, list_desktop_file) == 0) + + BamfView *list_view = BAMF_VIEW (l->data); + BamfApplication *list_app = BAMF_APPLICATION (l->data); + + const char *list_desktop_file = bamf_application_get_desktop_file (list_app); + + /* We try to match applications by desktop files */ + if (local_desktop_file && g_strcmp0 (local_desktop_file, list_desktop_file) == 0) { - created = FALSE; - g_object_unref (view); + matched_view = list_view; + break; + } + + /* If the primary search doesn't give out any result, we fallback + * to children window comparison */ + if (!matched_view) + { + GList *list_children, *ll; + list_children = bamf_application_get_cached_xids (list_app); + + for (ll = local_children; ll; ll = ll->next) + { + if (!BAMF_IS_WINDOW (ll->data)) + continue; + + guint32 local_xid = bamf_window_get_xid (BAMF_WINDOW (ll->data)); + + if (g_list_find (list_children, GUINT_TO_POINTER (local_xid))) + { + matched_view = list_view; + break; + } + } + } + } - view = BAMF_VIEW (l->data); - bamf_view_set_path (view, path); - g_object_ref_sink (view); + g_list_free (local_children); + } + else if (BAMF_IS_WINDOW (view)) + { + guint32 local_xid = bamf_window_get_xid (BAMF_WINDOW (view)); + + for (l = factory->priv->local_views; l; l = l->next) + { + if (!BAMF_IS_WINDOW (l->data)) + continue; + + BamfView *list_view = BAMF_VIEW (l->data); + BamfWindow *list_win = BAMF_WINDOW (l->data); + + guint32 list_xid = bamf_window_get_xid (list_win); + + /* We try to match windows by xid */ + if (local_xid != 0 && local_xid == list_xid) + { + matched_view = list_view; break; } } } - + + if (matched_view) + { + created = FALSE; + g_object_unref (view); + + view = matched_view; + bamf_view_set_path (view, path); + g_object_ref_sink (view); + } + if (view) { bamf_factory_register_view (factory, view, path); @@ -231,8 +345,7 @@ g_object_ref_sink (view); } } - - g_free (type); + return view; } diff -Nru bamf-0.2.116/lib/libbamf/bamf-factory.h bamf-0.2.118/lib/libbamf/bamf-factory.h --- bamf-0.2.116/lib/libbamf/bamf-factory.h 2012-04-26 09:19:57.000000000 +0000 +++ bamf-0.2.118/lib/libbamf/bamf-factory.h 2012-05-23 08:03:26.000000000 +0000 @@ -54,6 +54,15 @@ typedef struct _BamfFactoryClass BamfFactoryClass; typedef struct _BamfFactoryPrivate BamfFactoryPrivate; +typedef enum +{ + BAMF_FACTORY_VIEW, + BAMF_FACTORY_WINDOW, + BAMF_FACTORY_APPLICATION, + BAMF_FACTORY_INDICATOR, + BAMF_FACTORY_NONE +} BamfFactoryViewType; + struct _BamfFactory { GObject parent; @@ -71,6 +80,14 @@ BamfView * bamf_factory_view_for_path (BamfFactory * factory, const char * path); +BamfView * bamf_factory_view_for_path_type (BamfFactory * factory, + const char * path, + BamfFactoryViewType type); + +BamfView * bamf_factory_view_for_path_type_str (BamfFactory * factory, + const char * path, + const char * type); + BamfApplication * bamf_factory_app_for_file (BamfFactory * factory, const char * path, gboolean create); diff -Nru bamf-0.2.116/lib/libbamf/bamf-indicator.c bamf-0.2.118/lib/libbamf/bamf-indicator.c --- bamf-0.2.116/lib/libbamf/bamf-indicator.c 2012-04-26 09:19:57.000000000 +0000 +++ bamf-0.2.118/lib/libbamf/bamf-indicator.c 2012-05-23 08:03:26.000000000 +0000 @@ -214,6 +214,11 @@ self = BAMF_INDICATOR (view); priv = self->priv; + if (priv->proxy) + { + g_object_unref (priv->proxy); + } + priv->proxy = dbus_g_proxy_new_for_name (priv->connection, "org.ayatana.bamf", path, diff -Nru bamf-0.2.116/lib/libbamf/bamf-matcher.c bamf-0.2.118/lib/libbamf/bamf-matcher.c --- bamf-0.2.116/lib/libbamf/bamf-matcher.c 2012-04-26 09:19:57.000000000 +0000 +++ bamf-0.2.118/lib/libbamf/bamf-matcher.c 2012-05-23 08:03:26.000000000 +0000 @@ -144,8 +144,12 @@ BamfMatcher *matcher) { BamfView *view; + BamfFactory *factory = bamf_factory_get_default (); - view = bamf_factory_view_for_path (bamf_factory_get_default (), path); + view = bamf_factory_view_for_path_type_str (factory, path, type); + + if (!BAMF_IS_VIEW (view)) + return; g_signal_emit (matcher, matcher_signals[VIEW_OPENED], 0, view); } @@ -157,8 +161,9 @@ BamfMatcher *matcher) { BamfView *view; + BamfFactory *factory = bamf_factory_get_default (); - view = bamf_factory_view_for_path (bamf_factory_get_default (), path); + view = bamf_factory_view_for_path_type_str (factory, path, type); if (!BAMF_IS_VIEW (view)) return; @@ -172,14 +177,12 @@ char *new_path, BamfMatcher *matcher) { - BamfView *old_view = NULL; - BamfView *new_view = NULL; - - if (old_path && strlen (old_path) > 0) - old_view = bamf_factory_view_for_path (bamf_factory_get_default (), old_path); + BamfView *old_view; + BamfView *new_view; - if (new_path && strlen (new_path) > 0) - new_view = bamf_factory_view_for_path (bamf_factory_get_default (), new_path); + BamfFactory *factory = bamf_factory_get_default (); + old_view = bamf_factory_view_for_path_type (factory, old_path, BAMF_FACTORY_APPLICATION); + new_view = bamf_factory_view_for_path_type (factory, new_path, BAMF_FACTORY_APPLICATION); g_signal_emit (matcher, matcher_signals[ACTIVE_APPLICATION_CHANGED], 0, old_view, new_view); } @@ -190,14 +193,12 @@ char *new_path, BamfMatcher *matcher) { - BamfView *old_view = NULL; - BamfView *new_view = NULL; + BamfView *old_view; + BamfView *new_view; - if (old_path && strlen (old_path) > 0) - old_view = bamf_factory_view_for_path (bamf_factory_get_default (), old_path); - - if (new_path && strlen (new_path) > 0) - new_view = bamf_factory_view_for_path (bamf_factory_get_default (), new_path); + BamfFactory *factory = bamf_factory_get_default (); + old_view = bamf_factory_view_for_path_type (factory, old_path, BAMF_FACTORY_WINDOW); + new_view = bamf_factory_view_for_path_type (factory, new_path, BAMF_FACTORY_WINDOW); g_signal_emit (matcher, matcher_signals[ACTIVE_WINDOW_CHANGED], 0, old_view, new_view); } @@ -373,10 +374,17 @@ return NULL; } + if (app && app[0] == '\0') + { + g_free (app); + return NULL; + } + if (!app) return NULL; - view = bamf_factory_view_for_path (bamf_factory_get_default (), app); + BamfFactory *factory = bamf_factory_get_default (); + view = bamf_factory_view_for_path_type (factory, app, BAMF_FACTORY_APPLICATION); g_free (app); if (!BAMF_IS_APPLICATION (view)) @@ -390,7 +398,7 @@ { BamfMatcherPrivate *priv; BamfView *view; - char *app = NULL; + char *win = NULL; GError *error = NULL; g_return_val_if_fail (BAMF_IS_MATCHER (matcher), NULL); @@ -400,7 +408,7 @@ "ActiveWindow", &error, G_TYPE_INVALID, - G_TYPE_STRING, &app, + G_TYPE_STRING, &win, G_TYPE_INVALID)) { g_warning ("Failed to fetch path: %s", error->message); @@ -408,11 +416,18 @@ return NULL; } - if (!app) + if (win && win[0] == '\0') + { + g_free (win); + return NULL; + } + + if (!win) return NULL; - view = bamf_factory_view_for_path (bamf_factory_get_default (), app); - g_free (app); + BamfFactory *factory = bamf_factory_get_default (); + view = bamf_factory_view_for_path_type (factory, win, BAMF_FACTORY_WINDOW); + g_free (win); if (!BAMF_IS_WINDOW (view)) return NULL; @@ -455,10 +470,17 @@ return NULL; } + if (app && app[0] == '\0') + { + g_free (app); + return NULL; + } + if (!app) return NULL; - view = bamf_factory_view_for_path (bamf_factory_get_default (), app); + BamfFactory *factory = bamf_factory_get_default (); + view = bamf_factory_view_for_path_type (factory, app, BAMF_FACTORY_APPLICATION); g_free (app); @@ -522,14 +544,16 @@ return NULL; } - g_return_val_if_fail (array, NULL); + if (!array) + return NULL; + BamfFactory *factory = bamf_factory_get_default (); len = g_strv_length (array); for (i = len-1; i >= 0; i--) { - view = bamf_factory_view_for_path (bamf_factory_get_default (), array[i]); + view = bamf_factory_view_for_path_type (factory, array[i], BAMF_FACTORY_APPLICATION); - if (view) + if (BAMF_IS_APPLICATION (view)) result = g_list_prepend (result, view); } @@ -563,14 +587,16 @@ return NULL; } - g_return_val_if_fail (array, NULL); + if (!array) + return NULL; + BamfFactory *factory = bamf_factory_get_default (); len = g_strv_length (array); for (i = len-1; i >= 0; i--) { - view = bamf_factory_view_for_path (bamf_factory_get_default (), array[i]); + view = bamf_factory_view_for_path_type (factory, array[i], BAMF_FACTORY_WINDOW); - if (view) + if (BAMF_IS_WINDOW (view)) result = g_list_prepend (result, view); } @@ -606,14 +632,16 @@ return NULL; } - g_return_val_if_fail (array, NULL); + if (!array) + return NULL; + BamfFactory *factory = bamf_factory_get_default (); len = g_strv_length (array); for (i = len-1; i >= 0; i--) { - view = bamf_factory_view_for_path (bamf_factory_get_default (), array[i]); + view = bamf_factory_view_for_path_type (factory, array[i], BAMF_FACTORY_WINDOW); - if (view) + if (BAMF_IS_WINDOW (view)) result = g_list_prepend (result, view); } @@ -664,14 +692,16 @@ return NULL; } - g_return_val_if_fail (array, NULL); + if (!array) + return NULL; + BamfFactory *factory = bamf_factory_get_default (); len = g_strv_length (array); for (i = len-1; i >= 0; i--) { - view = bamf_factory_view_for_path (bamf_factory_get_default (), array[i]); + view = bamf_factory_view_for_path_type (factory, array[i], BAMF_FACTORY_APPLICATION); - if (view) + if (BAMF_IS_APPLICATION (view)) result = g_list_prepend (result, view); } diff -Nru bamf-0.2.116/lib/libbamf/bamf-view.c bamf-0.2.118/lib/libbamf/bamf-view.c --- bamf-0.2.116/lib/libbamf/bamf-view.c 2012-04-26 09:19:57.000000000 +0000 +++ bamf-0.2.118/lib/libbamf/bamf-view.c 2012-05-23 08:03:26.000000000 +0000 @@ -99,6 +99,8 @@ GList *cached_children; }; +static void bamf_view_unset_proxy (BamfView *self); + static void bamf_view_set_flag (BamfView *view, guint flag, gboolean value) { @@ -111,7 +113,7 @@ if (value) priv->set_flags |= flag; else - priv->set_flags = priv->set_flags & ~flag; + priv->set_flags &= ~flag; priv->checked_flags |= flag; } @@ -386,7 +388,7 @@ return BAMF_VIEW_GET_CLASS (self)->get_name (self); if (!bamf_view_remote_ready (self)) - return g_strdup(priv->local_name); + return g_strdup (priv->local_name); if (!dbus_g_proxy_call (priv->proxy, "Name", @@ -439,7 +441,7 @@ G_TYPE_STRING, &type, G_TYPE_INVALID)) { - g_warning ("Failed to fetch view type at %s: %s", dbus_g_proxy_get_path (priv->proxy), error->message); + g_warning ("Failed to fetch view type at %s: %s", dbus_g_proxy_get_path (priv->proxy), error ? error->message : ""); g_error_free (error); return NULL; } @@ -543,6 +545,16 @@ } static void +on_view_proxy_destroyed (GObject *proxy, gpointer user_data) +{ + BamfView *view = user_data; + g_return_if_fail (BAMF_IS_VIEW (view)); + + view->priv->checked_flags = 0x0; + view->priv->proxy = NULL; +} + +static void bamf_view_on_closed (DBusGProxy *proxy, BamfView *self) { BamfViewPrivate *priv; @@ -557,44 +569,9 @@ priv->cached_children = NULL; } - if (priv->sticky && priv->proxy) + if (priv->sticky) { - dbus_g_proxy_disconnect_signal (priv->proxy, - "ActiveChanged", - (GCallback) bamf_view_on_active_changed, - self); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "Closed", - (GCallback) bamf_view_on_closed, - self); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "ChildAdded", - (GCallback) bamf_view_on_child_added, - self); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "ChildRemoved", - (GCallback) bamf_view_on_child_removed, - self); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "RunningChanged", - (GCallback) bamf_view_on_running_changed, - self); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "UrgentChanged", - (GCallback) bamf_view_on_urgent_changed, - self); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "UserVisibleChanged", - (GCallback) bamf_view_on_user_visible_changed, - self); - g_object_unref (priv->proxy); - priv->proxy = NULL; + bamf_view_unset_proxy (self); } g_object_ref (self); @@ -656,6 +633,57 @@ } static void +bamf_view_unset_proxy (BamfView *self) +{ + BamfViewPrivate *priv; + + g_return_if_fail (BAMF_IS_VIEW (self)); + priv = self->priv; + + if (!priv->proxy) + return; + + dbus_g_proxy_disconnect_signal (priv->proxy, + "ActiveChanged", + (GCallback) bamf_view_on_active_changed, + self); + + dbus_g_proxy_disconnect_signal (priv->proxy, + "Closed", + (GCallback) bamf_view_on_closed, + self); + + dbus_g_proxy_disconnect_signal (priv->proxy, + "ChildAdded", + (GCallback) bamf_view_on_child_added, + self); + + dbus_g_proxy_disconnect_signal (priv->proxy, + "ChildRemoved", + (GCallback) bamf_view_on_child_removed, + self); + + dbus_g_proxy_disconnect_signal (priv->proxy, + "RunningChanged", + (GCallback) bamf_view_on_running_changed, + self); + + dbus_g_proxy_disconnect_signal (priv->proxy, + "UrgentChanged", + (GCallback) bamf_view_on_urgent_changed, + self); + + dbus_g_proxy_disconnect_signal (priv->proxy, + "UserVisibleChanged", + (GCallback) bamf_view_on_user_visible_changed, + self); + + g_signal_handlers_disconnect_by_func (priv->proxy, on_view_proxy_destroyed, self); + g_object_unref (priv->proxy); + priv->proxy = NULL; +} + +static void bamf_view_dispose (GObject *object) { BamfView *view; @@ -676,7 +704,7 @@ g_free (priv->type); priv->type = NULL; } - + if (priv->local_icon) { g_free (priv->local_icon); @@ -695,51 +723,7 @@ priv->cached_children = NULL; } - if (priv->proxy) - { - dbus_g_proxy_disconnect_signal (priv->proxy, - "ActiveChanged", - (GCallback) bamf_view_on_active_changed, - view); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "Closed", - (GCallback) bamf_view_on_closed, - view); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "ChildAdded", - (GCallback) bamf_view_on_child_added, - view); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "ChildRemoved", - (GCallback) bamf_view_on_child_removed, - view); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "RunningChanged", - (GCallback) bamf_view_on_running_changed, - view); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "UrgentChanged", - (GCallback) bamf_view_on_urgent_changed, - view); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "UserVisibleChanged", - (GCallback) bamf_view_on_user_visible_changed, - view); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "NameChanged", - (GCallback) bamf_view_on_name_changed, - view); - - g_object_unref (priv->proxy); - priv->proxy = NULL; - } + bamf_view_unset_proxy (view); G_OBJECT_CLASS (bamf_view_parent_class)->dispose (object); } @@ -753,6 +737,40 @@ } void +bamf_view_reset_flags (BamfView *view) +{ + BamfViewPrivate *priv; + g_return_if_fail (BAMF_IS_VIEW (view)); + + priv = view->priv; + priv->checked_flags = 0x0; + + if (bamf_view_user_visible (view)) + { + g_signal_emit (G_OBJECT(view), view_signals[VISIBLE_CHANGED], 0, TRUE); + g_object_notify (G_OBJECT (view), "user-visible"); + } + + if (bamf_view_is_active (view)) + { + g_signal_emit (G_OBJECT(view), view_signals[ACTIVE_CHANGED], 0, TRUE); + g_object_notify (G_OBJECT (view), "active"); + } + + if (bamf_view_is_running (view)) + { + g_signal_emit (G_OBJECT(view), view_signals[RUNNING_CHANGED], 0, TRUE); + g_object_notify (G_OBJECT (view), "running"); + } + + if (bamf_view_is_urgent (view)) + { + g_signal_emit (G_OBJECT(view), view_signals[URGENT_CHANGED], 0, TRUE); + g_object_notify (G_OBJECT (view), "urgent"); + } +} + +void bamf_view_set_path (BamfView *view, const char *path) { BamfViewPrivate *priv; @@ -766,18 +784,23 @@ { g_free (priv->path); } - + + bamf_view_unset_proxy (view); + priv->path = g_strdup (path); priv->proxy = dbus_g_proxy_new_for_name (priv->connection, "org.ayatana.bamf", priv->path, "org.ayatana.bamf.view"); + if (priv->proxy == NULL) { g_critical ("Unable to get org.ayatana.bamf.view view"); return; } + g_signal_connect (priv->proxy, "destroy", G_CALLBACK (on_view_proxy_destroyed), view); + dbus_g_proxy_add_signal (priv->proxy, "ActiveChanged", G_TYPE_BOOLEAN, @@ -868,32 +891,9 @@ if (bamf_view_is_sticky (view)) { - priv->checked_flags = 0x0; - - if (bamf_view_user_visible (view)) - { - g_signal_emit (G_OBJECT(view), view_signals[VISIBLE_CHANGED], 0, TRUE); - g_object_notify (G_OBJECT (view), "user-visible"); - } - - if (bamf_view_is_active (view)) - { - g_signal_emit (G_OBJECT(view), view_signals[ACTIVE_CHANGED], 0, TRUE); - g_object_notify (G_OBJECT (view), "active"); - } - - if (bamf_view_is_running (view)) - { - g_signal_emit (G_OBJECT(view), view_signals[RUNNING_CHANGED], 0, TRUE); - g_object_notify (G_OBJECT (view), "running"); - } - - if (bamf_view_is_urgent (view)) - { - g_signal_emit (G_OBJECT(view), view_signals[URGENT_CHANGED], 0, TRUE); - g_object_notify (G_OBJECT (view), "urgent"); - } + bamf_view_reset_flags (view); } + if (BAMF_VIEW_GET_CLASS (view)->set_path) BAMF_VIEW_GET_CLASS (view)->set_path (view, path); } diff -Nru bamf-0.2.116/lib/libbamf/bamf-view-private.h bamf-0.2.118/lib/libbamf/bamf-view-private.h --- bamf-0.2.116/lib/libbamf/bamf-view-private.h 2012-04-26 09:19:57.000000000 +0000 +++ bamf-0.2.118/lib/libbamf/bamf-view-private.h 2012-05-23 08:03:26.000000000 +0000 @@ -31,6 +31,8 @@ gboolean bamf_view_remote_ready (BamfView *view); +void bamf_view_reset_flags (BamfView *view); + void bamf_view_set_name (BamfView *view, const char *name); void bamf_view_set_icon (BamfView *view, const char *icon); diff -Nru bamf-0.2.116/lib/libbamf/bamf-window.c bamf-0.2.118/lib/libbamf/bamf-window.c --- bamf-0.2.116/lib/libbamf/bamf-window.c 2012-04-26 09:19:57.000000000 +0000 +++ bamf-0.2.118/lib/libbamf/bamf-window.c 2012-05-23 08:03:26.000000000 +0000 @@ -103,7 +103,8 @@ if (!path) return NULL; - transient = bamf_factory_view_for_path (bamf_factory_get_default (), path); + BamfFactory *factory = bamf_factory_get_default (); + transient = bamf_factory_view_for_path_type (factory, path, BAMF_FACTORY_WINDOW); g_free (path); if (!BAMF_IS_WINDOW (transient)) @@ -227,6 +228,31 @@ } static void +bamf_window_unset_proxy (BamfWindow *self) +{ + BamfWindowPrivate *priv; + + g_return_if_fail (BAMF_IS_WINDOW (self)); + priv = self->priv; + + if (!priv->proxy) + return; + + dbus_g_proxy_disconnect_signal (self->priv->proxy, + "MaximizedChanged", + (GCallback) bamf_window_on_maximized_changed, + self); + + dbus_g_proxy_disconnect_signal (self->priv->proxy, + "MonitorChanged", + (GCallback) bamf_window_on_monitor_changed, + self); + + g_object_unref (priv->proxy); + priv->proxy = NULL; +} + +static void bamf_window_set_path (BamfView *view, const char *path) { BamfWindow *self; @@ -235,6 +261,7 @@ self = BAMF_WINDOW (view); priv = self->priv; + bamf_window_unset_proxy (self); priv->proxy = dbus_g_proxy_new_for_name (priv->connection, "org.ayatana.bamf", path, @@ -379,26 +406,9 @@ bamf_window_dispose (GObject *object) { BamfWindow *self; - BamfWindowPrivate *priv; self = BAMF_WINDOW (object); - priv = self->priv; - - if (priv->proxy) - { - dbus_g_proxy_disconnect_signal (priv->proxy, - "MaximizedChanged", - (GCallback) bamf_window_on_maximized_changed, - self); - - dbus_g_proxy_disconnect_signal (priv->proxy, - "MonitorChanged", - (GCallback) bamf_window_on_monitor_changed, - self); - - g_object_unref (priv->proxy); - priv->proxy = NULL; - } + bamf_window_unset_proxy (self); if (G_OBJECT_CLASS (bamf_window_parent_class)->dispose) G_OBJECT_CLASS (bamf_window_parent_class)->dispose (object); @@ -466,7 +476,7 @@ { BamfWindow *self; self = g_object_new (BAMF_TYPE_WINDOW, NULL); - + bamf_view_set_path (BAMF_VIEW (self), path); return self; diff -Nru bamf-0.2.116/lib/libbamf/Makefile.am bamf-0.2.118/lib/libbamf/Makefile.am --- bamf-0.2.116/lib/libbamf/Makefile.am 2012-04-26 09:19:57.000000000 +0000 +++ bamf-0.2.118/lib/libbamf/Makefile.am 2012-05-23 08:03:26.000000000 +0000 @@ -40,6 +40,7 @@ libbamf_la_SOURCES = \ bamf-factory.h \ + bamf-application-private.h \ bamf-view-private.h \ $(sources_h) \ $(libbamf_sources) \ diff -Nru bamf-0.2.116/lib/libbamf/Makefile.in bamf-0.2.118/lib/libbamf/Makefile.in --- bamf-0.2.116/lib/libbamf/Makefile.in 2012-04-26 09:20:23.000000000 +0000 +++ bamf-0.2.118/lib/libbamf/Makefile.in 2012-05-23 08:05:49.000000000 +0000 @@ -345,6 +345,7 @@ libbamf_la_SOURCES = \ bamf-factory.h \ + bamf-application-private.h \ bamf-view-private.h \ $(sources_h) \ $(libbamf_sources) \ diff -Nru bamf-0.2.116/src/bamf-application.c bamf-0.2.118/src/bamf-application.c --- bamf-0.2.116/src/bamf-application.c 2012-04-26 09:19:57.000000000 +0000 +++ bamf-0.2.118/src/bamf-application.c 2012-05-23 08:03:26.000000000 +0000 @@ -120,17 +120,20 @@ if (self->priv->desktop_file) { keyfile = g_key_file_new(); - if (!g_key_file_load_from_file(keyfile, self->priv->desktop_file, G_KEY_FILE_NONE, NULL)) { + + if (!g_key_file_load_from_file(keyfile, self->priv->desktop_file, G_KEY_FILE_NONE, NULL)) + { g_key_file_free(keyfile); - return; - } + return; + } desktop = g_desktop_app_info_new_from_keyfile (keyfile); - if (!G_IS_APP_INFO (desktop)) { - g_key_file_free(keyfile); - return; - } + if (!G_IS_APP_INFO (desktop)) + { + g_key_file_free(keyfile); + return; + } gicon = g_app_info_get_icon (G_APP_INFO (desktop)); @@ -139,14 +142,15 @@ if (gicon) icon = g_icon_to_string (gicon); - if (g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP, STUB_KEY, NULL)) { - /* This will error to return false, which is okay as it seems - unlikely anyone will want to set this flag except to turn - off the stub menus. */ - self->priv->show_stubs = g_key_file_get_boolean (keyfile, - G_KEY_FILE_DESKTOP_GROUP, - STUB_KEY, NULL); - } + if (g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP, STUB_KEY, NULL)) + { + /* This will error to return false, which is okay as it seems + unlikely anyone will want to set this flag except to turn + off the stub menus. */ + self->priv->show_stubs = g_key_file_get_boolean (keyfile, + G_KEY_FILE_DESKTOP_GROUP, + STUB_KEY, NULL); + } if (g_key_file_has_key (keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-FullName", NULL)) { @@ -300,17 +304,20 @@ gboolean bamf_application_contains_similar_to_window (BamfApplication *self, - BamfWindow *window) + BamfWindow *bamf_window) { - gboolean result = FALSE; - const char *class, *owned_class; GList *children, *l; BamfView *child; g_return_val_if_fail (BAMF_IS_APPLICATION (self), FALSE); - g_return_val_if_fail (BAMF_IS_WINDOW (window), FALSE); + g_return_val_if_fail (BAMF_IS_WINDOW (bamf_window), FALSE); - class = bamf_legacy_window_get_class_name (bamf_window_get_window (window)); + BamfLegacyWindow *window = bamf_window_get_window (bamf_window); + const char *window_class = bamf_legacy_window_get_class_name (window); + const char *instance_name = bamf_legacy_window_get_class_instance_name (window); + + if (!window_class || !instance_name) + return FALSE; children = bamf_view_get_children (BAMF_VIEW (self)); for (l = children; l; l = l->next) @@ -320,16 +327,18 @@ if (!BAMF_IS_WINDOW (child)) continue; - owned_class = bamf_legacy_window_get_class_name (bamf_window_get_window (BAMF_WINDOW (child))); + window = bamf_window_get_window (BAMF_WINDOW (child)); + const char *owned_win_class = bamf_legacy_window_get_class_name (window); + const char *owned_instance = bamf_legacy_window_get_class_instance_name (window); - if (g_strcmp0 (class, owned_class) == 0) + if (g_strcmp0 (window_class, owned_win_class) == 0 && + g_strcmp0 (instance_name, owned_instance) == 0) { - result = TRUE; - break; + return TRUE; } } - return result; + return FALSE; } gboolean @@ -484,11 +493,12 @@ } static char * -bamf_application_favorite_from_list (BamfApplication *self, GList *list) +bamf_application_favorite_from_list (BamfApplication *self, GList *desktop_list) { BamfMatcher *matcher; GList *favs, *l; char *result = NULL; + const char *desktop_class; g_return_val_if_fail (BAMF_IS_APPLICATION (self), NULL); @@ -499,10 +509,15 @@ { for (l = favs; l; l = l->next) { - if (g_list_find_custom (list, l->data, (GCompareFunc) g_strcmp0)) + if (g_list_find_custom (desktop_list, l->data, (GCompareFunc) g_strcmp0)) { - result = l->data; - break; + desktop_class = bamf_matcher_get_desktop_file_class (matcher, l->data); + + if (!desktop_class || g_strcmp0 (self->priv->wmclass, desktop_class) == 0) + { + result = l->data; + break; + } } } } diff -Nru bamf-0.2.116/src/bamf-gdbus-browser-generated.c bamf-0.2.118/src/bamf-gdbus-browser-generated.c --- bamf-0.2.116/src/bamf-gdbus-browser-generated.c 2012-04-26 09:20:34.000000000 +0000 +++ bamf-0.2.118/src/bamf-gdbus-browser-generated.c 2012-05-23 08:04:41.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Generated by gdbus-codegen 2.32.0. DO NOT EDIT. + * Generated by gdbus-codegen 2.32.1. DO NOT EDIT. * * The license of this code is the same as for the source it was derived from. */ diff -Nru bamf-0.2.116/src/bamf-gdbus-browser-generated.h bamf-0.2.118/src/bamf-gdbus-browser-generated.h --- bamf-0.2.116/src/bamf-gdbus-browser-generated.h 2012-04-26 09:20:34.000000000 +0000 +++ bamf-0.2.118/src/bamf-gdbus-browser-generated.h 2012-05-23 08:04:41.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Generated by gdbus-codegen 2.32.0. DO NOT EDIT. + * Generated by gdbus-codegen 2.32.1. DO NOT EDIT. * * The license of this code is the same as for the source it was derived from. */ diff -Nru bamf-0.2.116/src/bamf-gdbus-generated.c bamf-0.2.118/src/bamf-gdbus-generated.c --- bamf-0.2.116/src/bamf-gdbus-generated.c 2012-04-26 09:20:34.000000000 +0000 +++ bamf-0.2.118/src/bamf-gdbus-generated.c 2012-05-23 08:04:41.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Generated by gdbus-codegen 2.32.0. DO NOT EDIT. + * Generated by gdbus-codegen 2.32.1. DO NOT EDIT. * * The license of this code is the same as for the source it was derived from. */ diff -Nru bamf-0.2.116/src/bamf-gdbus-generated.h bamf-0.2.118/src/bamf-gdbus-generated.h --- bamf-0.2.116/src/bamf-gdbus-generated.h 2012-04-26 09:20:34.000000000 +0000 +++ bamf-0.2.118/src/bamf-gdbus-generated.h 2012-05-23 08:04:41.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Generated by gdbus-codegen 2.32.0. DO NOT EDIT. + * Generated by gdbus-codegen 2.32.1. DO NOT EDIT. * * The license of this code is the same as for the source it was derived from. */ diff -Nru bamf-0.2.116/src/bamf-gdbus-indicator-source-generated.c bamf-0.2.118/src/bamf-gdbus-indicator-source-generated.c --- bamf-0.2.116/src/bamf-gdbus-indicator-source-generated.c 2012-04-26 09:20:34.000000000 +0000 +++ bamf-0.2.118/src/bamf-gdbus-indicator-source-generated.c 2012-05-23 08:04:42.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Generated by gdbus-codegen 2.32.0. DO NOT EDIT. + * Generated by gdbus-codegen 2.32.1. DO NOT EDIT. * * The license of this code is the same as for the source it was derived from. */ diff -Nru bamf-0.2.116/src/bamf-gdbus-indicator-source-generated.h bamf-0.2.118/src/bamf-gdbus-indicator-source-generated.h --- bamf-0.2.116/src/bamf-gdbus-indicator-source-generated.h 2012-04-26 09:20:34.000000000 +0000 +++ bamf-0.2.118/src/bamf-gdbus-indicator-source-generated.h 2012-05-23 08:04:42.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Generated by gdbus-codegen 2.32.0. DO NOT EDIT. + * Generated by gdbus-codegen 2.32.1. DO NOT EDIT. * * The license of this code is the same as for the source it was derived from. */ diff -Nru bamf-0.2.116/src/bamf-gdbus-view-generated.c bamf-0.2.118/src/bamf-gdbus-view-generated.c --- bamf-0.2.116/src/bamf-gdbus-view-generated.c 2012-04-26 09:20:34.000000000 +0000 +++ bamf-0.2.118/src/bamf-gdbus-view-generated.c 2012-05-23 08:04:41.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Generated by gdbus-codegen 2.32.0. DO NOT EDIT. + * Generated by gdbus-codegen 2.32.1. DO NOT EDIT. * * The license of this code is the same as for the source it was derived from. */ diff -Nru bamf-0.2.116/src/bamf-gdbus-view-generated.h bamf-0.2.118/src/bamf-gdbus-view-generated.h --- bamf-0.2.116/src/bamf-gdbus-view-generated.h 2012-04-26 09:20:34.000000000 +0000 +++ bamf-0.2.118/src/bamf-gdbus-view-generated.h 2012-05-23 08:04:41.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Generated by gdbus-codegen 2.32.0. DO NOT EDIT. + * Generated by gdbus-codegen 2.32.1. DO NOT EDIT. * * The license of this code is the same as for the source it was derived from. */ diff -Nru bamf-0.2.116/src/bamf-matcher.c bamf-0.2.118/src/bamf-matcher.c --- bamf-0.2.116/src/bamf-matcher.c 2012-04-26 09:19:57.000000000 +0000 +++ bamf-0.2.118/src/bamf-matcher.c 2012-05-23 08:03:26.000000000 +0000 @@ -210,6 +210,7 @@ static void bamf_matcher_prepare_path_change (BamfMatcher *self, const gchar *desktop_file, ViewChangeType change_type) { BamfMatcherPrivate *priv; + BamfApplication *app; if (desktop_file == NULL) return; @@ -219,7 +220,9 @@ /* the app was already running (ADDED) / had more instances which are still * there (REMOVED) */ - if (bamf_matcher_get_application_by_desktop_file (self, desktop_file)) + app = bamf_matcher_get_application_by_desktop_file (self, desktop_file); + + if (BAMF_IS_APPLICATION (app) && bamf_view_is_running (BAMF_VIEW (app))) { return; } @@ -656,9 +659,11 @@ } static gboolean -exec_string_should_be_processed (BamfMatcher *self, - char *exec) +exec_string_should_be_processed (const char *exec) { + if (!exec) + return TRUE; + return !g_str_has_prefix (exec, "ooffice") && !g_str_has_prefix (exec, "libreoffice"); } @@ -826,7 +831,7 @@ return; } - if (exec_string_should_be_processed (self, exec)) + if (exec_string_should_be_processed (exec)) { /** * Set of nasty hacks which should be removed some day. We wish to keep the full exec @@ -936,7 +941,7 @@ gchar **parts = g_strsplit (line, "\t", 3); exec = parts[1]; - if (exec_string_should_be_processed (self, exec)) + if (exec_string_should_be_processed (exec)) { char *tmp = trim_exec_string (self, exec); g_free (parts[1]); @@ -1374,6 +1379,9 @@ { const char *class_name = bamf_legacy_window_get_class_name (window); + if (!class_name) + return FALSE; + return (g_str_has_prefix (class_name, "LibreOffice") || g_str_has_prefix (class_name, "libreoffice") || g_str_has_prefix (class_name, "OpenOffice") || @@ -1528,7 +1536,7 @@ is_web_app_window (BamfMatcher *self, BamfLegacyWindow *window) { const char *window_class = bamf_legacy_window_get_class_name (window); - const char *instance_name = bamf_legacy_window_get_class_instance_name(window); + const char *instance_name = bamf_legacy_window_get_class_instance_name (window); // Chrome/Chromium uses url wm_class strings to represent its web apps. // These apps will still have the same parent pid and hints as the main chrome @@ -1540,15 +1548,20 @@ gboolean valid_app = FALSE; - if (g_strcmp0 (window_class, "Google-chrome") == 0 && - g_strcmp0 (instance_name, "google-chrome") != 0) - { - valid_app = TRUE; - } - else if (g_strcmp0 (window_class, "Chromium-browser") == 0 && - g_strcmp0 (instance_name, "chromium-browser") != 0) + if (instance_name && window_class) { - valid_app = TRUE; + if (g_strcmp0 (window_class, "Google-chrome") == 0 && + g_strcmp0 (instance_name, "google-chrome") != 0 && + !g_str_has_prefix (instance_name, "Google-chrome")) + { + valid_app = TRUE; + } + else if (g_strcmp0 (window_class, "Chromium-browser") == 0 && + g_strcmp0 (instance_name, "chromium-browser") != 0 && + !g_str_has_prefix (instance_name, "Chromium-browser")) + { + valid_app = TRUE; + } } return valid_app; @@ -1615,31 +1628,50 @@ static GList * bamf_matcher_possible_applications_for_window (BamfMatcher *self, - BamfWindow *bamf_window) + BamfWindow *bamf_window, + const char **target_class_out) { BamfMatcherPrivate *priv; BamfLegacyWindow *window; GList *desktop_files = NULL, *l; char *desktop_file = NULL; - char *desktop_class = NULL; + const char *desktop_class = NULL; + const char *class_name = NULL; + const char *instance_name = NULL; + const char *target_class = NULL; + gboolean filter_by_wmclass = FALSE; g_return_val_if_fail (BAMF_IS_WINDOW (bamf_window), NULL); g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL); priv = self->priv; window = bamf_window_get_window (bamf_window); - desktop_file = get_window_hint (window, _NET_WM_DESKTOP_FILE); + class_name = bamf_legacy_window_get_class_name (window); + instance_name = bamf_legacy_window_get_class_instance_name (window); - const char *class_name = bamf_legacy_window_get_class_name (window); - const char *instance_name = bamf_legacy_window_get_class_instance_name (window); - gboolean known_desktop_class = bamf_matcher_has_instance_class_desktop_file (self, instance_name); + target_class = instance_name; + filter_by_wmclass = bamf_matcher_has_instance_class_desktop_file (self, target_class); + + if (!filter_by_wmclass) + { + if (is_web_app_window (self, window)) + { + // This ensures that a new application is created even for unknown webapps + filter_by_wmclass = TRUE; + } + else + { + target_class = class_name; + filter_by_wmclass = bamf_matcher_has_instance_class_desktop_file (self, target_class); + } + } if (desktop_file) { - desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file); + desktop_class = bamf_matcher_get_desktop_file_class (self, desktop_file); - if (!known_desktop_class || g_strcmp0 (desktop_class, desktop_file) == 0) + if ((!filter_by_wmclass && !desktop_class) || g_strcmp0 (desktop_class, target_class) == 0) { desktop_files = g_list_prepend (desktop_files, desktop_file); } @@ -1665,9 +1697,9 @@ if (desktop_file) { - desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file); + desktop_class = bamf_matcher_get_desktop_file_class (self, desktop_file); - if (!known_desktop_class || g_strcmp0 (desktop_class, instance_name) == 0) + if ((!filter_by_wmclass && !desktop_class) || g_strcmp0 (desktop_class, target_class) == 0) { if (!g_list_find_custom (desktop_files, desktop_file, (GCompareFunc) g_strcmp0)) @@ -1698,10 +1730,10 @@ { gboolean append = FALSE; - if (instance_name) + if (target_class) { - desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file); - if (!known_desktop_class || g_strcmp0 (desktop_class, instance_name) == 0) + desktop_class = bamf_matcher_get_desktop_file_class (self, desktop_file); + if ((!filter_by_wmclass && !desktop_class) || g_strcmp0 (desktop_class, target_class) == 0) { append = TRUE; } @@ -1730,7 +1762,7 @@ } } } - + desktop_files = g_list_insert_before (desktop_files, last, desktop_file); } else @@ -1743,34 +1775,40 @@ g_list_free (pid_list); } - if (!desktop_files && known_desktop_class) + if (!desktop_files && filter_by_wmclass) + { + desktop_files = bamf_matcher_get_class_matching_desktop_files (self, target_class); + } + + if (target_class_out) { - desktop_files = bamf_matcher_get_class_matching_desktop_files (self, instance_name); + *target_class_out = target_class; } return desktop_files; } -static void -bamf_matcher_setup_window_state (BamfMatcher *self, - BamfWindow *bamf_window) +static BamfApplication * +bamf_matcher_get_application_for_window (BamfMatcher *self, + BamfWindow *bamf_window, + gboolean *new_application) { GList *possible_apps, *l; BamfLegacyWindow *window; - const gchar *app_class; + const gchar *win_class_name; + const gchar *target_class = NULL; + const gchar *app_class = NULL; const gchar *app_desktop = NULL; BamfApplication *app = NULL, *best = NULL; - g_return_if_fail (BAMF_IS_MATCHER (self)); - g_return_if_fail (BAMF_IS_WINDOW (bamf_window)); + g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL); + g_return_val_if_fail (BAMF_IS_WINDOW (bamf_window), NULL); window = bamf_window_get_window (bamf_window); + win_class_name = bamf_legacy_window_get_class_name (window); - possible_apps = bamf_matcher_possible_applications_for_window (self, bamf_window); - const char *win_instance = bamf_legacy_window_get_class_instance_name (window); - const char *win_class_name = bamf_legacy_window_get_class_name (window); - - app_class = win_instance; + possible_apps = bamf_matcher_possible_applications_for_window (self, bamf_window, &target_class); + app_class = target_class; /* Loop over every possible desktop file that could match the window, and try * to reuse an already-opened window that uses it. @@ -1789,7 +1827,7 @@ const gchar *app_desktop_class; app_desktop_class = bamf_application_get_wmclass (app); - if (win_instance && app_desktop_class && strcasecmp (win_instance, app_desktop_class) == 0) + if (target_class && app_desktop_class && strcasecmp (target_class, app_desktop_class) == 0) { best = app; break; @@ -1819,7 +1857,7 @@ const gchar *best_desktop_class; best_app_class = bamf_application_get_wmclass (best); - best_desktop_class = g_hash_table_lookup (self->priv->desktop_class_table, best_desktop); + best_desktop_class = bamf_matcher_get_desktop_file_class (self, best_desktop); /* We compare the two classes using their "distance" from the * desidered class value */ @@ -1857,7 +1895,7 @@ if (bamf_application_contains_similar_to_window (app, bamf_window)) { - if (win_instance && g_strcmp0 (win_instance, app_desktop_class) == 0) + if (target_class && g_strcmp0 (target_class, app_desktop_class) == 0) { best = app; break; @@ -1886,12 +1924,19 @@ } bamf_application_set_wmclass (best, app_class); - bamf_matcher_register_view_stealing_ref (self, BAMF_VIEW (best)); - } - bamf_view_add_child (BAMF_VIEW (best), BAMF_VIEW (bamf_window)); + if (new_application) + *new_application = TRUE; + } + else + { + if (new_application) + *new_application = FALSE; + } g_list_free_full (possible_apps, g_free); + + return best; } /* Ensures that the window hint is set if a registered pid matches, and that set window hints @@ -1962,6 +2007,7 @@ handle_raw_window (BamfMatcher *self, BamfLegacyWindow *window) { BamfWindow *bamfwindow; + BamfApplication *bamfapplication; g_return_if_fail (BAMF_IS_MATCHER (self)); g_return_if_fail (BAMF_IS_LEGACY_WINDOW (window)); @@ -1979,7 +2025,15 @@ bamfwindow = bamf_window_new (window); bamf_matcher_register_view_stealing_ref (self, BAMF_VIEW (bamfwindow)); - bamf_matcher_setup_window_state (self, bamfwindow); + gboolean new_app = FALSE; + bamfapplication = bamf_matcher_get_application_for_window (self, bamfwindow, &new_app); + + if (new_app) + { + bamf_matcher_register_view_stealing_ref (self, BAMF_VIEW (bamfapplication)); + } + + bamf_view_add_child (BAMF_VIEW (bamfapplication), BAMF_VIEW (bamfwindow)); } static void @@ -2193,6 +2247,8 @@ bamf_matcher_load_desktop_file (BamfMatcher * self, const char * desktop_file) { + GList *vl, *wl; + g_return_if_fail (BAMF_IS_MATCHER (self)); load_desktop_file_to_table (self, @@ -2200,6 +2256,36 @@ self->priv->desktop_file_table, self->priv->desktop_id_table, self->priv->desktop_class_table); + + /* If an application with no .desktop file has windows that matches + * the new added .desktop file, then we try to re-match them. */ + for (vl = self->priv->views; vl; vl = vl->next) + { + if (!BAMF_IS_APPLICATION (vl->data)) + continue; + + BamfApplication *app = BAMF_APPLICATION (vl->data); + + if (!bamf_application_get_desktop_file (app)) + { + GList *children = bamf_view_get_children (BAMF_VIEW (app)); + + for (wl = children; wl; wl = wl->next) + { + if (!BAMF_IS_WINDOW (wl->data)) + continue; + + BamfWindow *win = BAMF_WINDOW (wl->data); + GList *desktops = bamf_matcher_possible_applications_for_window (self, win, NULL); + + if (g_list_find_custom (desktops, desktop_file, (GCompareFunc) g_strcmp0)) + { + BamfLegacyWindow *legacy_window = bamf_window_get_window (win); + bamf_legacy_window_reopen (legacy_window); + } + } + } + } } void @@ -2233,6 +2319,15 @@ } } +const char * +bamf_matcher_get_desktop_file_class (BamfMatcher * self, const char * desktop_file) +{ + g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL); + g_return_val_if_fail (desktop_file, NULL); + + return g_hash_table_lookup (self->priv->desktop_class_table, desktop_file); +} + static int x_error_handler (Display *display, XErrorEvent *event) { @@ -2337,7 +2432,6 @@ return (idx_a < idx_b) ? -1 : 1; } - GVariant * bamf_matcher_get_window_stack_for_monitor (BamfMatcher *matcher, gint monitor) { @@ -2505,8 +2599,8 @@ if (g_list_find_custom (priv->favorites, fav, (GCompareFunc) g_strcmp0)) continue; - priv->favorites = g_list_prepend (priv->favorites, g_strdup (fav)); bamf_matcher_load_desktop_file (matcher, fav); + priv->favorites = g_list_prepend (priv->favorites, g_strdup (fav)); } g_signal_emit (matcher, matcher_signals[FAVORITES_CHANGED], 0); diff -Nru bamf-0.2.116/src/bamf-matcher.h bamf-0.2.118/src/bamf-matcher.h --- bamf-0.2.116/src/bamf-matcher.h 2012-04-26 09:19:57.000000000 +0000 +++ bamf-0.2.118/src/bamf-matcher.h 2012-05-23 08:03:26.000000000 +0000 @@ -74,6 +74,9 @@ const char *application, gint pid); +const char * bamf_matcher_get_desktop_file_class (BamfMatcher * self, + const char * desktop_file); + const char * bamf_matcher_get_active_application (BamfMatcher *matcher); const char * bamf_matcher_get_active_window (BamfMatcher *matcher);