[nautilus-actions] Define new BaseIUnique interface
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Define new BaseIUnique interface
- Date: Wed, 11 Jan 2012 22:09:14 +0000 (UTC)
commit b1dd5595d9d22157568d394535a48fc74b48f18c
Author: Pierre Wieser <pwieser trychlos org>
Date: Sun Jan 8 11:49:26 2012 +0100
Define new BaseIUnique interface
Isolete in an interface the 'is application unique' machinery.
ChangeLog | 7 +
src/nact/Makefile.am | 2 +
src/nact/base-iunique.c | 302 +++++++++++++++++++++++++++++++++++++++++++++++
src/nact/base-iunique.h | 79 ++++++++++++
4 files changed, 390 insertions(+), 0 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index bd3b7d6..ddb941d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2012-01-08 Pierre Wieser <pwieser trychlos org>
+
+ * src/nact/base-iunique.c:
+ * src/nact/base-iunique.h: New BaseIUnique interface.
+
+ * src/nact/Makefile.am: Updated accordingly.
+
2012-01-06 Pierre Wieser <pwieser trychlos org>
* configure.ac: Now requires gtk-doc >= 1.16.
diff --git a/src/nact/Makefile.am b/src/nact/Makefile.am
index 516feb9..10397ba 100644
--- a/src/nact/Makefile.am
+++ b/src/nact/Makefile.am
@@ -58,6 +58,8 @@ nautilus_actions_config_tool_SOURCES = \
base-dialog.h \
base-gtk-utils.c \
base-gtk-utils.h \
+ base-iunique.c \
+ base-iunique.h \
base-keysyms.h \
base-window.c \
base-window.h \
diff --git a/src/nact/base-iunique.c b/src/nact/base-iunique.c
new file mode 100644
index 0000000..72ba147
--- /dev/null
+++ b/src/nact/base-iunique.c
@@ -0,0 +1,302 @@
+/*
+ * Nautilus-Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010, 2011, 2012 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program 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.
+ *
+ * This Program 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 this Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Frederic Ruaudel <grumz grumz net>
+ * Rodrigo Moya <rodrigo gnome-db org>
+ * Pierre Wieser <pwieser trychlos org>
+ * ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+#include <string.h>
+#include <unique/unique.h>
+
+#include "base-iunique.h"
+#include "base-window.h"
+
+/* private interface data
+ */
+struct _BaseIUniqueInterfacePrivate {
+ void *empty; /* so that gcc -pedantic is happy */
+};
+
+/* BaseIUnique properties, set as data association against the GObject instance
+ */
+#define BASE_PROP_HANDLE "base-prop-iunique-handle"
+#define BASE_PROP_INITIALIZED "base-prop-iunique-initialized"
+
+static guint st_initializations = 0; /* interface initialisation count */
+
+static GType register_type( void );
+static void interface_base_init( BaseIUniqueInterface *klass );
+static void interface_base_finalize( BaseIUniqueInterface *klass );
+
+static void instance_init( BaseIUnique *instance );
+static void on_instance_finalized( gpointer user_data, BaseIUnique *instance );
+
+#if 0
+static UniqueResponse on_unique_message_received( UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time, gpointer user_data );
+#endif
+
+static const gchar *m_get_application_name( const BaseIUnique *instance );
+
+GType
+base_iunique_get_type( void )
+{
+ static GType iface_type = 0;
+
+ if( !iface_type ){
+ iface_type = register_type();
+ }
+
+ return( iface_type );
+}
+
+static GType
+register_type( void )
+{
+ static const gchar *thisfn = "base_iunique_register_type";
+ GType type;
+
+ static const GTypeInfo info = {
+ sizeof( BaseIUniqueInterface ),
+ ( GBaseInitFunc ) interface_base_init,
+ ( GBaseFinalizeFunc ) interface_base_finalize,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ NULL
+ };
+
+ g_debug( "%s", thisfn );
+
+ type = g_type_register_static( G_TYPE_INTERFACE, "BaseIUnique", &info, 0 );
+
+ g_type_interface_add_prerequisite( type, G_TYPE_OBJECT );
+
+ return( type );
+}
+
+static void
+interface_base_init( BaseIUniqueInterface *klass )
+{
+ static const gchar *thisfn = "base_iunique_interface_base_init";
+
+ if( !st_initializations ){
+
+ g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
+
+ klass->private = g_new0( BaseIUniqueInterfacePrivate, 1 );
+ }
+
+ st_initializations += 1;
+}
+
+static void
+interface_base_finalize( BaseIUniqueInterface *klass )
+{
+ static const gchar *thisfn = "base_iunique_interface_base_finalize";
+
+ st_initializations -= 1;
+
+ if( !st_initializations ){
+
+ g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
+
+ g_free( klass->private );
+ }
+}
+
+static void
+instance_init( BaseIUnique *instance )
+{
+ static const gchar *thisfn = "base_iunique_instance_init";
+
+ if( ! ( gboolean ) GPOINTER_TO_UINT( g_object_get_data( G_OBJECT( instance ), BASE_PROP_INITIALIZED ))){
+
+ g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
+
+ g_object_weak_ref( G_OBJECT( instance ), ( GWeakNotify ) on_instance_finalized, NULL );
+
+ g_object_set_data( G_OBJECT( instance ), BASE_PROP_INITIALIZED, GUINT_TO_POINTER( TRUE ));
+ }
+}
+
+static void
+on_instance_finalized( gpointer user_data, BaseIUnique *instance )
+{
+ static const gchar *thisfn = "base_iunique_on_instance_finalized";
+
+ g_debug( "%s: instance=%p, user_data=%p", thisfn, ( void * ) instance, ( void * ) user_data );
+
+ UniqueApp *handle = ( UniqueApp * ) g_object_get_data( G_OBJECT( instance ), BASE_PROP_HANDLE );
+
+ if( handle ){
+ g_return_if_fail( UNIQUE_IS_APP( handle ));
+ g_object_unref( handle );
+ }
+}
+
+#if 0
+/*
+ * Relying on libunique to detect another instance already running.
+ *
+ * A replacement is available with GLib 2.28 in GApplication, but only
+ * GLib 2.30 (Fedora 16) provides a "non-unique" property.
+ */
+static gboolean
+init_unique_app( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_init_unique_app";
+ gboolean ret;
+ BaseApplicationPrivate *priv;
+ gboolean is_first;
+ gchar *msg;
+
+ g_debug( "%s: application=%p", thisfn, ( void * ) application );
+
+ ret = TRUE;
+ priv = application->private;
+
+ if( priv->unique_app_name && strlen( priv->unique_app_name )){
+
+ handle = unique_app_new( unique_app_name, NULL );
+ is_first = !unique_app_is_running( handle );
+
+ if( !is_first ){
+ unique_app_send_message( handle, UNIQUE_ACTIVATE, NULL );
+ /* i18n: application name */
+ msg = g_strdup_printf(
+ _( "Another instance of %s is already running.\n"
+ "Please switch back to it." ),
+ priv->application_name );
+ base_window_display_error_dlg( NULL, _( "The application is not unique" ), msg );
+ g_free( msg );
+ ret = FALSE;
+ priv->code = BASE_EXIT_CODE_UNIQUE_APP;
+ /* default from libunique is actually to activate the first window
+ * so we rely on the default..
+ */
+ } else {
+ g_signal_connect(
+ priv->unique_app_handle,
+ "message-received",
+ G_CALLBACK( on_unique_message_received ),
+ application );
+ }
+ }
+
+ return( ret );
+}
+#endif
+
+/*
+ * Relying on libunique to detect if another instance is already running.
+ *
+ * A replacement is available with GLib 2.28 in GApplication, but only
+ * GLib 2.30 (Fedora 16) provides a "non-unique" capability.
+ */
+gboolean
+base_iunique_init_name( BaseIUnique *instance, const gchar *unique_app_name )
+{
+ static const gchar *thisfn = "base_iunique_init_name";
+ gboolean ret;
+ gboolean is_first;
+ gchar *msg;
+ UniqueApp *handle;
+
+ g_return_val_if_fail( BASE_IS_IUNIQUE( instance ), FALSE );
+
+ instance_init( instance );
+
+ g_debug( "%s: instance=%p, unique_app_name=%s", thisfn, ( void * ) instance, unique_app_name );
+
+ ret = TRUE;
+
+ if( unique_app_name && strlen( unique_app_name )){
+
+ handle = unique_app_new( unique_app_name, NULL );
+ is_first = !unique_app_is_running( handle );
+
+ if( !is_first ){
+ unique_app_send_message( handle, UNIQUE_ACTIVATE, NULL );
+ /* i18n: application name */
+ msg = g_strdup_printf(
+ _( "Another instance of %s is already running.\n"
+ "Please switch back to it." ),
+ m_get_application_name( instance ));
+ base_window_display_error_dlg( NULL, _( "The application is not unique" ), msg );
+ g_free( msg );
+ ret = FALSE;
+#if 0
+ /* default from libunique is actually to activate the first window
+ * so we rely on the default..
+ */
+ } else {
+ g_signal_connect(
+ handle,
+ "message-received",
+ G_CALLBACK( on_unique_message_received ),
+ instance );
+#endif
+ } else {
+ g_object_set_data( G_OBJECT( instance ), BASE_PROP_HANDLE, handle );
+ }
+ }
+
+ return( ret );
+}
+
+#if 0
+static UniqueResponse
+on_unique_message_received(
+ UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time, BaseIUnique *instance )
+{
+ static const gchar *thisfn = "base_iunique_on_unique_message_received";
+ UniqueResponse resp = UNIQUE_RESPONSE_OK;
+
+ switch( command ){
+ case UNIQUE_ACTIVATE:
+ g_debug( "%s: received message UNIQUE_ACTIVATE", thisfn );
+ break;
+ default:
+ resp = UNIQUE_RESPONSE_PASSTHROUGH;
+ break;
+ }
+
+ return( resp );
+}
+#endif
+
+static const gchar *
+m_get_application_name( const BaseIUnique *instance )
+{
+ return( BASE_IUNIQUE_GET_INTERFACE( instance )->get_application_name( instance ));
+}
diff --git a/src/nact/base-iunique.h b/src/nact/base-iunique.h
new file mode 100644
index 0000000..dbb0bcd
--- /dev/null
+++ b/src/nact/base-iunique.h
@@ -0,0 +1,79 @@
+/*
+ * Nautilus-Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010, 2011, 2012 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program 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.
+ *
+ * This Program 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 this Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Frederic Ruaudel <grumz grumz net>
+ * Rodrigo Moya <rodrigo gnome-db org>
+ * Pierre Wieser <pwieser trychlos org>
+ * ... and many others (see AUTHORS)
+ */
+
+#ifndef __BASE_IUNIQUE_H__
+#define __BASE_IUNIQUE_H__
+
+/**
+ * SECTION: base_iunique
+ * @short_description: #BaseIUnique interface definition.
+ * @include: nact/base-iunique.h
+ *
+ * This interface implements the features to make an application
+ * unique, i.e. cjheck that we run only one instance of it.
+ */
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define BASE_IUNIQUE_TYPE ( base_iunique_get_type())
+#define BASE_IUNIQUE( object ) ( G_TYPE_CHECK_INSTANCE_CAST( object, BASE_IUNIQUE_TYPE, BaseIUnique ))
+#define BASE_IS_IUNIQUE( object ) ( G_TYPE_CHECK_INSTANCE_TYPE( object, BASE_IUNIQUE_TYPE ))
+#define BASE_IUNIQUE_GET_INTERFACE( instance ) ( G_TYPE_INSTANCE_GET_INTERFACE(( instance ), BASE_IUNIQUE_TYPE, BaseIUniqueInterface ))
+
+typedef struct _BaseIUnique BaseIUnique;
+typedef struct _BaseIUniqueInterfacePrivate BaseIUniqueInterfacePrivate;
+
+typedef struct {
+ /*< private >*/
+ GTypeInterface parent;
+ BaseIUniqueInterfacePrivate *private;
+
+ /*< public >*/
+ /**
+ * get_application_name:
+ * @instance: this #NAIExporter instance.
+ *
+ * Returns: the 'display' name of the application.
+ */
+ const gchar * ( *get_application_name )( const BaseIUnique *instance );
+}
+ BaseIUniqueInterface;
+
+GType base_iunique_get_type ( void );
+
+gboolean base_iunique_init_name ( BaseIUnique *instance, const gchar *unique_app_name );
+
+void base_iunique_watch_window( BaseIUnique *instance, GtkWindow *toplevel );
+
+G_END_DECLS
+
+#endif /* __BASE_IUNIQUE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]