[nautilus-actions] New BaseISession interface
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] New BaseISession interface
- Date: Wed, 11 Jan 2012 22:10:44 +0000 (UTC)
commit 47e9f321f94b786b8d52393eb8665d2f286d4c07
Author: Pierre Wieser <pwieser trychlos org>
Date: Mon Jan 9 23:32:48 2012 +0100
New BaseISession interface
ChangeLog | 6 +
src/nact/Makefile.am | 2 +
src/nact/base-application.c | 120 ++++----------------
src/nact/base-isession.c | 263 +++++++++++++++++++++++++++++++++++++++++++
src/nact/base-isession.h | 68 +++++++++++
5 files changed, 363 insertions(+), 96 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 72dfa41..37a9b5f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2012-01-09 Pierre Wieser <pwieser trychlos org>
+ * src/nact/base-isession.c:
+ * src/nact/base-isession.h: New BaseISession interface.
+
+ * src/nact/Makefile.am:
+ * src/nact/base-application.c (init_session_manager): Updated accordingly.
+
* src/nact/base-application.h: Update comments.
* src/nact/base-window.c:
diff --git a/src/nact/Makefile.am b/src/nact/Makefile.am
index 10397ba..da0d906 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-isession.c \
+ base-isession.h \
base-iunique.c \
base-iunique.h \
base-keysyms.h \
diff --git a/src/nact/base-application.c b/src/nact/base-application.c
index eb1f849..5a009b9 100644
--- a/src/nact/base-application.c
+++ b/src/nact/base-application.c
@@ -36,8 +36,8 @@
#include <string.h>
#include "base-application.h"
+#include "base-isession.h"
#include "base-iunique.h"
-#include "egg-sm-client.h"
/* private class data
*/
@@ -60,12 +60,6 @@ struct _BaseApplicationPrivate {
gchar *icon_name;
gchar *unique_app_name;
int code;
-
- /* internals
- */
- EggSMClient *sm_client;
- gulong sm_client_quit_handler_id;
- gulong sm_client_quit_requested_handler_id;
};
/* instance properties
@@ -89,6 +83,7 @@ static GObjectClass *st_parent_class = NULL;
static GType register_type( void );
static void class_init( BaseApplicationClass *klass );
+static void isession_iface_init( BaseISessionInterface *iface, void *user_data );
static void iunique_iface_init( BaseIUniqueInterface *iface, void *user_data );
static const gchar *iunique_get_application_name( const BaseIUnique *instance );
static void instance_init( GTypeInstance *instance, gpointer klass );
@@ -103,19 +98,30 @@ static gboolean init_gtk( BaseApplication *application );
static gboolean v_manage_options( BaseApplication *application );
static gboolean init_unique_manager( BaseApplication *application );
static gboolean init_session_manager( BaseApplication *application );
-static void session_manager_client_quit_cb( EggSMClient *client, BaseApplication *application );
-static void session_manager_client_quit_requested_cb( EggSMClient *client, BaseApplication *application );
static gboolean init_icon_name( BaseApplication *application );
static gboolean v_init_application( BaseApplication *application );
static gboolean v_create_windows( BaseApplication *application );
+/*
+ * the BaseISessionInterface interface is registered here because
+ * the interface requires its implementation to be of BaseApplication
+ * type. So we have to first register the type class before trying to
+ * register the type interface.
+ */
GType
base_application_get_type( void )
{
static GType application_type = 0;
+ static const GInterfaceInfo isession_iface_info = {
+ ( GInterfaceInitFunc ) isession_iface_init,
+ NULL,
+ NULL
+ };
+
if( !application_type ){
application_type = register_type();
+ g_type_add_interface_static( application_type, BASE_ISESSION_TYPE, &isession_iface_info );
}
return( application_type );
@@ -243,6 +249,14 @@ class_init( BaseApplicationClass *klass )
}
static void
+isession_iface_init( BaseISessionInterface *iface, void *user_data )
+{
+ static const gchar *thisfn = "base_application_isession_iface_init";
+
+ g_debug( "%s: iface=%p, user_data=%p", thisfn, ( void * ) iface, ( void * ) user_data );
+}
+
+static void
iunique_iface_init( BaseIUniqueInterface *iface, void *user_data )
{
static const gchar *thisfn = "base_application_iunique_iface_init";
@@ -402,20 +416,6 @@ instance_dispose( GObject *application )
self->private->dispose_has_run = TRUE;
- if( self->private->sm_client_quit_handler_id &&
- g_signal_handler_is_connected( self->private->sm_client, self->private->sm_client_quit_handler_id )){
- g_signal_handler_disconnect( self->private->sm_client, self->private->sm_client_quit_handler_id );
- }
-
- if( self->private->sm_client_quit_requested_handler_id &&
- g_signal_handler_is_connected( self->private->sm_client, self->private->sm_client_quit_requested_handler_id )){
- g_signal_handler_disconnect( self->private->sm_client, self->private->sm_client_quit_requested_handler_id );
- }
-
- if( self->private->sm_client ){
- g_object_unref( self->private->sm_client );
- }
-
/* chain up to the parent class */
if( G_OBJECT_CLASS( st_parent_class )->dispose ){
G_OBJECT_CLASS( st_parent_class )->dispose( application );
@@ -661,87 +661,15 @@ static gboolean
init_session_manager( BaseApplication *application )
{
static const gchar *thisfn = "base_application_init_session_manager";
- BaseApplicationPrivate *priv;
g_debug( "%s: application=%p", thisfn, ( void * ) application );
- priv = application->private;
-
- egg_sm_client_set_mode( EGG_SM_CLIENT_MODE_NO_RESTART );
- priv->sm_client = egg_sm_client_get();
- egg_sm_client_startup();
- g_debug( "%s: sm_client=%p", thisfn, ( void * ) priv->sm_client );
-
- priv->sm_client_quit_handler_id =
- g_signal_connect(
- priv->sm_client,
- "quit-requested",
- G_CALLBACK( session_manager_client_quit_requested_cb ),
- application );
-
- priv->sm_client_quit_requested_handler_id =
- g_signal_connect(
- priv->sm_client,
- "quit",
- G_CALLBACK( session_manager_client_quit_cb ),
- application );
+ base_isession_init( BASE_ISESSION( application ));
return( TRUE );
}
/*
- * cleanly terminate the main window when exiting the session
- */
-static void
-session_manager_client_quit_cb( EggSMClient *client, BaseApplication *application )
-{
- static const gchar *thisfn = "base_application_session_manager_client_quit_cb";
-
- g_return_if_fail( BASE_IS_APPLICATION( application ));
-
- if( !application->private->dispose_has_run ){
-
- g_debug( "%s: client=%p, application=%p", thisfn, ( void * ) client, ( void * ) application );
-
-#if 0
- if( application->private->main_window ){
-
- g_return_if_fail( BASE_IS_WINDOW( application->private->main_window ));
- g_object_unref( application->private->main_window );
- application->private->main_window = NULL;
- }
-#endif
- }
-}
-
-/*
- * the session manager advertises us that the session is about to exit
- */
-static void
-session_manager_client_quit_requested_cb( EggSMClient *client, BaseApplication *application )
-{
- static const gchar *thisfn = "base_application_session_manager_client_quit_requested_cb";
- gboolean willing_to = TRUE;
-
- g_return_if_fail( BASE_IS_APPLICATION( application ));
-
- if( !application->private->dispose_has_run ){
-
- g_debug( "%s: client=%p, application=%p", thisfn, ( void * ) client, ( void * ) application );
-
-#if 0
- if( application->private->main_window ){
-
- g_return_if_fail( BASE_IS_WINDOW( application->private->main_window ));
- willing_to = base_window_is_willing_to_quit( application->private->main_window );
- }
-#endif
- }
-
- egg_sm_client_will_quit( client, willing_to );
-}
-
-/*
* From GTK+ Reference Manual:
* Sets an icon to be used as fallback for windows that haven't had
* gtk_window_set_icon_list() called on them from a named themed icon.
diff --git a/src/nact/base-isession.c b/src/nact/base-isession.c
new file mode 100644
index 0000000..1e5470c
--- /dev/null
+++ b/src/nact/base-isession.c
@@ -0,0 +1,263 @@
+/*
+ * 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 "base-application.h"
+#include "base-isession.h"
+#include "egg-sm-client.h"
+
+/* private interface data
+ */
+struct _BaseISessionInterfacePrivate {
+ void *empty; /* so that gcc -pedantic is happy */
+};
+
+/* private properties, set against the instance
+ */
+typedef struct {
+ EggSMClient *sm_client;
+ gulong sm_client_quit_handler_id;
+ gulong sm_client_quit_requested_handler_id;
+}
+ ISessionStr;
+
+/* Above ISessionStr struct is set as a BaseISession pseudo-property
+ * of the instance.
+ */
+#define BASE_PROP_ISESSION "base-prop-isession"
+
+static guint st_initializations = 0; /* interface initialisation count */
+
+static GType register_type( void );
+static void interface_base_init( BaseISessionInterface *klass );
+static void interface_base_finalize( BaseISessionInterface *klass );
+
+static void on_instance_finalized( gpointer user_data, BaseISession *instance );
+static void client_quit_requested_cb( EggSMClient *client, BaseISession *instance );
+static void client_quit_cb( EggSMClient *client, BaseISession *instance );
+static ISessionStr *get_isession_str( BaseISession *instance );
+
+GType
+base_isession_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_isession_register_type";
+ GType type;
+
+ static const GTypeInfo info = {
+ sizeof( BaseISessionInterface ),
+ ( 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, "BaseISession", &info, 0 );
+
+ g_type_interface_add_prerequisite( type, BASE_APPLICATION_TYPE );
+
+ return( type );
+}
+
+static void
+interface_base_init( BaseISessionInterface *klass )
+{
+ static const gchar *thisfn = "base_isession_interface_base_init";
+
+ if( !st_initializations ){
+
+ g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
+
+ klass->private = g_new0( BaseISessionInterfacePrivate, 1 );
+ }
+
+ st_initializations += 1;
+}
+
+static void
+interface_base_finalize( BaseISessionInterface *klass )
+{
+ static const gchar *thisfn = "base_isession_interface_base_finalize";
+
+ st_initializations -= 1;
+
+ if( !st_initializations ){
+
+ g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
+
+ g_free( klass->private );
+ }
+}
+
+void
+base_isession_init( BaseISession *instance )
+{
+ static const gchar *thisfn = "base_isession_init";
+ ISessionStr *str;
+
+ g_return_if_fail( BASE_IS_ISESSION( instance ));
+
+ g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
+
+ str = get_isession_str( instance );
+
+ /* set a weak reference to be advertised when the instance is finalized
+ */
+ g_object_weak_ref( G_OBJECT( instance ), ( GWeakNotify ) on_instance_finalized, NULL );
+
+ /* initialize the session manager
+ */
+ egg_sm_client_set_mode( EGG_SM_CLIENT_MODE_NO_RESTART );
+ str->sm_client = egg_sm_client_get();
+ egg_sm_client_startup();
+ g_debug( "%s: sm_client=%p", thisfn, ( void * ) str->sm_client );
+
+ str->sm_client_quit_handler_id =
+ g_signal_connect(
+ str->sm_client,
+ "quit-requested",
+ G_CALLBACK( client_quit_requested_cb ),
+ instance );
+
+ str->sm_client_quit_requested_handler_id =
+ g_signal_connect(
+ str->sm_client,
+ "quit",
+ G_CALLBACK( client_quit_cb ),
+ instance );
+}
+
+static void
+on_instance_finalized( gpointer user_data, BaseISession *instance )
+{
+ static const gchar *thisfn = "base_isession_on_instance_finalized";
+ ISessionStr *str;
+
+ g_debug( "%s: instance=%p, user_data=%p", thisfn, ( void * ) instance, ( void * ) user_data );
+
+ str = get_isession_str( instance );
+
+ if( str->sm_client_quit_handler_id &&
+ g_signal_handler_is_connected( str->sm_client, str->sm_client_quit_handler_id )){
+ g_signal_handler_disconnect( str->sm_client, str->sm_client_quit_handler_id );
+ }
+
+ if( str->sm_client_quit_requested_handler_id &&
+ g_signal_handler_is_connected( str->sm_client, str->sm_client_quit_requested_handler_id )){
+ g_signal_handler_disconnect( str->sm_client, str->sm_client_quit_requested_handler_id );
+ }
+
+ if( str->sm_client ){
+ g_object_unref( str->sm_client );
+ }
+
+ g_free( str );
+}
+
+/*
+ * the session manager advertises us that the session is about to exit
+ */
+static void
+client_quit_requested_cb( EggSMClient *client, BaseISession *instance )
+{
+ static const gchar *thisfn = "base_isession_client_quit_requested_cb";
+ gboolean willing_to = TRUE;
+
+ g_return_if_fail( BASE_IS_ISESSION( instance ));
+
+ g_debug( "%s: client=%p, instance=%p", thisfn, ( void * ) client, ( void * ) instance );
+
+#if 0
+ if( application->private->main_window ){
+
+ g_return_if_fail( BASE_IS_WINDOW( application->private->main_window ));
+ willing_to = base_window_is_willing_to_quit( application->private->main_window );
+ }
+#endif
+
+ egg_sm_client_will_quit( client, willing_to );
+}
+
+/*
+ * cleanly terminate the main window when exiting the session
+ */
+static void
+client_quit_cb( EggSMClient *client, BaseISession *instance )
+{
+ static const gchar *thisfn = "base_isession_client_quit_cb";
+
+ g_return_if_fail( BASE_IS_ISESSION( instance ));
+
+ g_debug( "%s: client=%p, instance=%p", thisfn, ( void * ) client, ( void * ) instance );
+
+#if 0
+ if( application->private->main_window ){
+
+ g_return_if_fail( BASE_IS_WINDOW( application->private->main_window ));
+ g_object_unref( application->private->main_window );
+ application->private->main_window = NULL;
+ }
+#endif
+}
+
+static ISessionStr *
+get_isession_str( BaseISession *instance )
+{
+ ISessionStr *str;
+
+ str = ( ISessionStr * ) g_object_get_data( G_OBJECT( instance ), BASE_PROP_ISESSION );
+
+ if( !str ){
+ str = g_new0( ISessionStr, 1 );
+ g_object_set_data( G_OBJECT( instance ), BASE_PROP_ISESSION, str );
+ }
+
+ return( str );
+}
diff --git a/src/nact/base-isession.h b/src/nact/base-isession.h
new file mode 100644
index 0000000..874ce52
--- /dev/null
+++ b/src/nact/base-isession.h
@@ -0,0 +1,68 @@
+/*
+ * 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_ISESSION_H__
+#define __BASE_ISESSION_H__
+
+/**
+ * SECTION: base_isession
+ * @short_description: #BaseISession interface definition.
+ * @include: nact/base-isession.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_ISESSION_TYPE ( base_isession_get_type())
+#define BASE_ISESSION( object ) ( G_TYPE_CHECK_INSTANCE_CAST( object, BASE_ISESSION_TYPE, BaseISession ))
+#define BASE_IS_ISESSION( object ) ( G_TYPE_CHECK_INSTANCE_TYPE( object, BASE_ISESSION_TYPE ))
+#define BASE_ISESSION_GET_INTERFACE( instance ) ( G_TYPE_INSTANCE_GET_INTERFACE(( instance ), BASE_ISESSION_TYPE, BaseISessionInterface ))
+
+typedef struct _BaseISession BaseISession;
+typedef struct _BaseISessionInterfacePrivate BaseISessionInterfacePrivate;
+
+typedef struct {
+ /*< private >*/
+ GTypeInterface parent;
+ BaseISessionInterfacePrivate *private;
+}
+ BaseISessionInterface;
+
+GType base_isession_get_type( void );
+
+void base_isession_init ( BaseISession *instance );
+
+G_END_DECLS
+
+#endif /* __BASE_ISESSION_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]