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:
parent
e56a34000b
commit
317281f87c
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
11
gtk/conf.c
11
gtk/conf.c
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
21
gtk/main.c
21
gtk/main.c
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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"
|
||||
};
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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* );
|
||||
|
||||
|
|
28
gtk/util.c
28
gtk/util.c
|
@ -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 )
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue