Don't show an error when transmission is run twice

Instead, present the main window. This commit also auto-generates
the dbus bindings.
This commit is contained in:
Mukund Sivaraman 2008-08-17 12:39:26 +00:00
parent e56a34000b
commit 317281f87c
15 changed files with 99 additions and 145 deletions

View File

@ -163,6 +163,13 @@ if test "x$build_gtk" = "xyes"; then
[use_dbus_glib=no])
AC_SUBST(DBUS_GLIB_LIBS)
AC_SUBST(DBUS_GLIB_CFLAGS)
if test "x$use_dbus_glib" = "xyes"; then
AC_PATH_PROG(DBUS_BINDING_TOOL, dbus-binding-tool, no)
if test "x$DBUS_BINDING_TOOL" = xno; then
AC_MSG_WARN([Cannot find dbus-binding-tool])
use_dbus_glib="no (dbus-binding-tool not found)"
fi
fi
if test "x$use_dbus_glib" = "xyes"; then
AC_DEFINE([HAVE_DBUS_GLIB], 1)
fi

View File

@ -49,6 +49,8 @@ noinst_HEADERS = \
bin_PROGRAMS = transmission
dbus_generated_sources = tr-core-dbus.h
transmission_SOURCES = \
actions.c \
add-dialog.c \
@ -71,7 +73,8 @@ transmission_SOURCES = \
tr-prefs.c \
tr-torrent.c \
tr-window.c \
util.c
util.c \
$(dbus_generated_sources)
dist_man_MANS = transmission.1
@ -106,3 +109,9 @@ EXTRA_DIST = \
DISTCLEANFILES = \
transmission.desktop
CLEANFILES = $(dbus_generated_sources)
$(srcdir)/tr-core-dbus.c: tr-core-dbus.h
tr-core-dbus.h: $(srcdir)/tr-core-dbus.xml
$(DBUS_BINDING_TOOL) --mode=glib-server --prefix=tr_core $< > $(@F)

View File

@ -129,7 +129,8 @@ static GtkActionEntry entries[] =
{ "show-about-dialog", GTK_STOCK_ABOUT, NULL, NULL, NULL, G_CALLBACK(action_cb) },
{ "help", GTK_STOCK_HELP, N_("_Contents"), "F1", NULL, G_CALLBACK(action_cb) },
{ "update-tracker", GTK_STOCK_NETWORK,
N_("Ask Tracker for _More Peers"), NULL, NULL, G_CALLBACK(action_cb) }
N_("Ask Tracker for _More Peers"), NULL, NULL, G_CALLBACK(action_cb) },
{ "present-main-window", NULL, NULL, NULL, NULL, G_CALLBACK(action_cb) },
};
typedef struct

View File

@ -71,9 +71,9 @@ cf_init(const char *dir, char **errstr)
/* errstr may be NULL, this might be called before GTK is initialized */
static gboolean
lockfile(const char * filename, char **errstr)
lockfile(const char * filename, tr_lockfile_state_t *tr_state, char **errstr)
{
const int state = tr_lockfile( filename );
const tr_lockfile_state_t state = tr_lockfile( filename );
const gboolean success = state == TR_LOCKFILE_SUCCESS;
if( errstr ) switch( state ) {
@ -90,6 +90,9 @@ lockfile(const char * filename, char **errstr)
break;
}
if( tr_state != NULL)
*tr_state = state;
return success;
}
@ -111,10 +114,10 @@ cf_removelocks( void )
/* errstr may be NULL, this might be called before GTK is initialized */
gboolean
cf_lock( char ** errstr )
cf_lock( tr_lockfile_state_t *tr_state, char ** errstr )
{
char * path = getLockFilename( );
const gboolean didLock = lockfile( path, errstr );
const gboolean didLock = lockfile( path, tr_state, errstr );
if( didLock )
gl_lockpath = g_strdup( path );
g_atexit( cf_removelocks );

View File

@ -66,7 +66,7 @@ gboolean pref_flag_eval( pref_flag_t val, const char * key );
gboolean
cf_init(const char *confdir, char **errstr);
gboolean
cf_lock(char **errstr);
cf_lock(tr_lockfile_state_t *tr_state, char **errstr);
void
cf_check_older_configs(void);

View File

@ -347,6 +347,7 @@ main( int argc, char ** argv )
gboolean startminimized = FALSE;
char * domain = "transmission";
char * configDir = NULL;
tr_lockfile_state_t tr_state;
GOptionEntry entries[] = {
{ "paused", 'p', 0, G_OPTION_ARG_NONE, &startpaused,
@ -397,7 +398,7 @@ main( int argc, char ** argv )
/* either get a lockfile s.t. this is the one instance of
* transmission that's running, OR if there are files to
* be added, delegate that to the running instance via dbus */
didlock = cf_lock( &err );
didlock = cf_lock( &tr_state, &err );
argfiles = checkfilenames( argc-1, argv+1 );
if( !didlock && argfiles )
{
@ -408,6 +409,11 @@ main( int argc, char ** argv )
if( delegated )
err = NULL;
}
else if( (!didlock) && (tr_state == TR_LOCKFILE_ELOCK) )
{
gtr_dbus_present_window();
err = NULL;
}
if( didlock && ( didinit || cf_init( configDir, &err ) ) )
{
@ -576,13 +582,13 @@ clearTag( guint * tag )
}
static void
toggleMainWindow( struct cbdata * cbdata )
toggleMainWindow( struct cbdata * cbdata, gboolean present )
{
GtkWindow * window = GTK_WINDOW( cbdata->wind );
const int hide = !cbdata->minimized;
static int x=0, y=0;
if( hide )
if( (!present) && hide )
{
gtk_window_get_position( window, &x, &y );
clearTag( &cbdata->idle_hide_mainwindow_tag );
@ -592,7 +598,8 @@ toggleMainWindow( struct cbdata * cbdata )
else
{
gtk_window_set_skip_taskbar_hint( window, FALSE );
gtk_window_move( window, x, y );
if ( x != 0 && y != 0 )
gtk_window_move( window, x, y );
gtk_widget_show( GTK_WIDGET( window ) );
gtk_window_deiconify( window );
#if GTK_CHECK_VERSION(2,8,0)
@ -1357,7 +1364,11 @@ doAction ( const char * action_name, gpointer user_data )
}
else if (!strcmp (action_name, "toggle-main-window"))
{
toggleMainWindow( data );
toggleMainWindow( data, FALSE );
}
else if (!strcmp (action_name, "present-main-window"))
{
toggleMainWindow( data, TRUE );
}
else g_error ("Unhandled action: %s", action_name );

View File

@ -1,122 +0,0 @@
/* Generated by dbus-binding-tool; do not edit! */
#ifndef __dbus_glib_marshal_tr_core_MARSHAL_H__
#define __dbus_glib_marshal_tr_core_MARSHAL_H__
#include <glib-object.h>
G_BEGIN_DECLS
#ifdef G_ENABLE_DEBUG
#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
#define g_marshal_value_peek_char(v) g_value_get_char (v)
#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
#define g_marshal_value_peek_int(v) g_value_get_int (v)
#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
#define g_marshal_value_peek_long(v) g_value_get_long (v)
#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
#define g_marshal_value_peek_float(v) g_value_get_float (v)
#define g_marshal_value_peek_double(v) g_value_get_double (v)
#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
#define g_marshal_value_peek_param(v) g_value_get_param (v)
#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
#define g_marshal_value_peek_object(v) g_value_get_object (v)
#else /* !G_ENABLE_DEBUG */
/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
* Do not access GValues directly in your code. Instead, use the
* g_value_get_*() functions
*/
#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
#define g_marshal_value_peek_char(v) (v)->data[0].v_int
#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
#define g_marshal_value_peek_int(v) (v)->data[0].v_int
#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
#define g_marshal_value_peek_long(v) (v)->data[0].v_long
#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
#define g_marshal_value_peek_float(v) (v)->data[0].v_float
#define g_marshal_value_peek_double(v) (v)->data[0].v_double
#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
#endif /* !G_ENABLE_DEBUG */
/* BOOLEAN:STRING,POINTER,POINTER (/tmp/dbus-binding-tool-c-marshallers.0AFVAU:1) */
extern void dbus_glib_marshal_tr_core_BOOLEAN__STRING_POINTER_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data);
void
dbus_glib_marshal_tr_core_BOOLEAN__STRING_POINTER_POINTER (GClosure *closure,
GValue *return_value G_GNUC_UNUSED,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint G_GNUC_UNUSED,
gpointer marshal_data)
{
typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER) (gpointer data1,
gpointer arg_1,
gpointer arg_2,
gpointer arg_3,
gpointer data2);
register GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
gboolean v_return;
g_return_if_fail (return_value != NULL);
g_return_if_fail (n_param_values == 4);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback);
v_return = callback (data1,
g_marshal_value_peek_string (param_values + 1),
g_marshal_value_peek_pointer (param_values + 2),
g_marshal_value_peek_pointer (param_values + 3),
data2);
g_value_set_boolean (return_value, v_return);
}
G_END_DECLS
#endif /* __dbus_glib_marshal_tr_core_MARSHAL_H__ */
#include <dbus/dbus-glib.h>
static const DBusGMethodInfo dbus_glib_tr_core_methods[] = {
{ (GCallback) tr_core_add_file, dbus_glib_marshal_tr_core_BOOLEAN__STRING_POINTER_POINTER, 0 },
};
const DBusGObjectInfo dbus_glib_tr_core_object_info = {
0,
dbus_glib_tr_core_methods,
1,
"com.transmissionbt.Transmission\0AddFile\0S\0filename\0I\0s\0handled\0O\0F\0N\0b\0\0\0",
"\0",
"\0"
};

View File

@ -5,6 +5,9 @@
<arg type="b" name="handled" direction="out"/>
<arg type="s" name="filename" direction="in"/>
</method>
<method name="PresentWindow">
<arg type="b" name="handled" direction="out"/>
</method>
</interface>
</node>

View File

@ -44,6 +44,7 @@
#include "tr-prefs.h"
#include "tr-torrent.h"
#include "util.h"
#include "actions.h"
static void maybeInhibitHibernation( TrCore * core );
@ -785,6 +786,16 @@ tr_core_add_file( TrCore * core,
return TRUE;
}
gboolean
tr_core_present_window( TrCore * core UNUSED,
gboolean * success,
GError ** err UNUSED )
{
action_activate( "present-main-window" );
*success = TRUE;
return TRUE;
}
void
tr_core_add_list( TrCore * core,
GSList * torrentFiles,

View File

@ -130,6 +130,9 @@ void tr_core_add_list( TrCore * self,
/** Add a torrent. */
gboolean tr_core_add_file( TrCore*, const char * filename, gboolean * setme_success, GError ** err );
/** Present the main window */
gboolean tr_core_present_window( TrCore*, gboolean * setme_success, GError ** err );
/** Add a torrent. */
void tr_core_add_torrent( TrCore*, TrTorrent* );

View File

@ -500,6 +500,34 @@ gtr_dbus_add_torrent( const char * filename )
return success;
}
gboolean
gtr_dbus_present_window()
{
static gboolean success = FALSE;
#ifdef HAVE_DBUS_GLIB
DBusGProxy * proxy = NULL;
GError * err = NULL;
DBusGConnection * conn;
if(( conn = dbus_g_bus_get( DBUS_BUS_SESSION, &err )))
proxy = dbus_g_proxy_new_for_name (conn, VALUE_SERVICE_NAME,
VALUE_SERVICE_OBJECT_PATH,
VALUE_SERVICE_INTERFACE );
else if( err )
g_message( "err: %s", err->message );
if( proxy )
dbus_g_proxy_call( proxy, "PresentWindow", &err,
G_TYPE_INVALID,
G_TYPE_BOOLEAN, &success,
G_TYPE_INVALID );
if( err )
g_message( "err: %s", err->message );
g_object_unref( proxy );
dbus_g_connection_unref( conn );
#endif
return success;
}
GtkWidget *
tr_button_new_from_stock( const char * stock,
const char * mnemonic )

View File

@ -80,6 +80,7 @@ checkfilenames( int argc, char ** argv );
void gtr_open_file( const char * path );
gboolean gtr_dbus_add_torrent( const char * filename );
gboolean gtr_dbus_present_window( void );
char* gtr_get_help_url( void );

View File

@ -603,10 +603,10 @@ tr_getClutchDir( const tr_session * session UNUSED )
****
***/
int
tr_lockfile_state_t
tr_lockfile( const char * filename )
{
int ret;
tr_lockfile_state_t ret;
#ifdef WIN32

View File

@ -56,14 +56,6 @@ void tr_lockLock ( tr_lock * );
void tr_lockUnlock ( tr_lock * );
int tr_lockHave ( const tr_lock * );
enum
{
TR_LOCKFILE_SUCCESS,
TR_LOCKFILE_EOPEN,
TR_LOCKFILE_ELOCK
};
int tr_lockfile ( const char * filename );
tr_lockfile_state_t tr_lockfile ( const char * filename );
#endif

View File

@ -1179,6 +1179,13 @@ typedef enum tr_errno
}
tr_errno;
typedef enum
{
TR_LOCKFILE_SUCCESS = 0,
TR_LOCKFILE_EOPEN,
TR_LOCKFILE_ELOCK
} tr_lockfile_state_t;
tr_torrent_status tr_torrentGetStatus( tr_torrent * );
enum