Changeset 13107


Ignore:
Timestamp:
Dec 10, 2011, 7:00:50 PM (10 years ago)
Author:
jordan
Message:

(trunk libT) #4372 "make notification and system sounds configurable" -- instead of using notify-send, use GDBus on the org.freedesktop.Notifications API. Patch by fmuellner.

Location:
trunk/gtk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/conf.c

    r12682 r13107  
    9494    tr_bencDictAddStr ( d, PREF_KEY_STATUSBAR_STATS, "total-ratio" );
    9595
    96     tr_bencDictAddStr ( d, PREF_KEY_TORRENT_ADDED_NOTIFICATION_COMMAND, "notify-send -c transfer -i transmission '%s' '%s'" );
    9796    tr_bencDictAddBool( d, PREF_KEY_TORRENT_ADDED_NOTIFICATION_ENABLED, true );
    98     tr_bencDictAddStr ( d, PREF_KEY_TORRENT_COMPLETE_NOTIFICATION_COMMAND, "notify-send -c transfer.complete -i transmission '%s' '%s'" );
    9997    tr_bencDictAddBool( d, PREF_KEY_TORRENT_COMPLETE_NOTIFICATION_ENABLED, true );
    10098    tr_bencDictAddStr ( d, PREF_KEY_TORRENT_COMPLETE_SOUND_COMMAND, "canberra-gtk-play -i complete-download -d 'transmission torrent downloaded'" );
  • trunk/gtk/main.c

    r13067 r13107  
    4747#include "makemeta-ui.h"
    4848#include "msgwin.h"
     49#include "notify.h"
    4950#include "open-dialog.h"
    5051#include "relocate.h"
     
    644645    g_mkdir_with_parents( cbdata.config_dir, 0755 );
    645646
     647    /* init notifications */
     648    gtr_notify_init( );
     649
    646650    /* init the application for the specified config dir */
    647651    stat( cbdata.config_dir, &sb );
  • trunk/gtk/notify.c

    r12676 r13107  
    1111 */
    1212
     13#include <string.h> /* strcmp() */
     14
     15#include <gio/gio.h>
     16
    1317#include <glib/gi18n.h>
    1418#include "conf.h"
    1519#include "notify.h"
    1620#include "tr-prefs.h"
     21#include "util.h"
     22
     23#define NOTIFICATIONS_DBUS_NAME           "org.freedesktop.Notifications"
     24#define NOTIFICATIONS_DBUS_CORE_OBJECT    "/org/freedesktop/Notifications"
     25#define NOTIFICATIONS_DBUS_CORE_INTERFACE "org.freedesktop.Notifications"
     26
     27static GDBusProxy *proxy = NULL;
     28static GHashTable *active_notifications = NULL;
     29static gboolean server_supports_actions = FALSE;
     30
     31typedef struct _TrNotification
     32{
     33    guint    id;
     34    TrCore * core;
     35    int      torrent_id;
     36} TrNotification;
     37
     38static void
     39tr_notification_free( gpointer data )
     40{
     41    TrNotification * n = data;
     42    if( n->core )
     43        g_object_unref( G_OBJECT( n->core ) );
     44    g_free( n );
     45}
     46
     47static void
     48get_capabilities_callback( GObject      * source,
     49                           GAsyncResult * res,
     50                           gpointer       user_data UNUSED )
     51{
     52    GVariant  *result;
     53    char     **caps;
     54    int        i;
     55
     56    result = g_dbus_proxy_call_finish( G_DBUS_PROXY( source ), res, NULL );
     57    if( !result || !g_variant_is_of_type( result, G_VARIANT_TYPE( "(as)" ) ) )
     58    {
     59        if( result )
     60            g_variant_unref( result );
     61        return;
     62    }
     63
     64    g_variant_get( result, "(^a&s)", &caps );
     65    for( i = 0; caps[i]; i++ )
     66    {
     67        if( strcmp( caps[i], "actions" ) == 0 )
     68        {
     69            server_supports_actions = TRUE;
     70            break;
     71        }
     72    }
     73    g_free( caps );
     74    g_variant_unref( result );
     75}
     76
     77static void
     78g_signal_callback( GDBusProxy * proxy UNUSED,
     79                   char       * sender_name UNUSED,
     80                   char       * signal_name,
     81                   GVariant   * params,
     82                   gpointer     user_data UNUSED )
     83{
     84    TrNotification * n;
     85    guint id;
     86
     87    g_return_if_fail( g_variant_is_of_type( params, G_VARIANT_TYPE( "(u*)" ) ) );
     88
     89    g_variant_get( params, "(u*)", &id, NULL );
     90    n = g_hash_table_lookup( active_notifications,
     91                             GINT_TO_POINTER( (int *) &id ) );
     92    if( n == NULL )
     93        return;
     94
     95    if( strcmp( signal_name, "NotificationClosed" ) == 0 )
     96    {
     97        g_hash_table_remove( active_notifications,
     98                             GINT_TO_POINTER( (int *) &n->id ) );
     99    }
     100    else if( strcmp( signal_name, "ActionInvoked" ) == 0 &&
     101             g_variant_is_of_type( params, G_VARIANT_TYPE( "(us)" ) ) )
     102    {
     103        char * action;
     104        tr_torrent * tor;
     105
     106        tor = gtr_core_find_torrent( n->core, n->torrent_id );
     107        if( tor == NULL )
     108            return;
     109
     110        g_variant_get( params, "(u&s)", NULL, &action );
     111        if( strcmp( action, "folder" ) == 0 )
     112        {
     113            gtr_core_open_folder( n->core, n->torrent_id );
     114        }
     115        else if( strcmp( action, "file" ) == 0)
     116        {
     117            const tr_info * inf = tr_torrentInfo( tor );
     118            const char * dir = tr_torrentGetDownloadDir( tor );
     119            char * path = g_build_filename( dir, inf->files[0].name, NULL );
     120            gtr_open_file( path );
     121            g_free( path );
     122        }
     123    }
     124}
     125
     126static void
     127dbus_proxy_ready_callback( GObject      * source UNUSED,
     128                           GAsyncResult * res,
     129                           gpointer       user_data UNUSED )
     130{
     131    proxy = g_dbus_proxy_new_for_bus_finish( res, NULL );
     132    if( proxy == NULL )
     133    {
     134        g_warning( "Failed to create proxy for %s", NOTIFICATIONS_DBUS_NAME );
     135        return;
     136    }
     137
     138    g_signal_connect( proxy, "g-signal",
     139                      G_CALLBACK( g_signal_callback ), NULL );
     140    g_dbus_proxy_call( proxy,
     141                       "GetCapabilities",
     142                       g_variant_new( "()" ),
     143                       G_DBUS_CALL_FLAGS_NONE, -1, NULL,
     144                       get_capabilities_callback, NULL );
     145}
     146
     147void
     148gtr_notify_init( void )
     149{
     150    active_notifications = g_hash_table_new_full( g_int_hash, g_int_equal,
     151                                                  NULL, tr_notification_free );
     152    g_dbus_proxy_new_for_bus( G_BUS_TYPE_SESSION,
     153                              G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
     154                              NULL,
     155                              NOTIFICATIONS_DBUS_NAME,
     156                              NOTIFICATIONS_DBUS_CORE_OBJECT,
     157                              NOTIFICATIONS_DBUS_CORE_INTERFACE,
     158                              NULL, dbus_proxy_ready_callback, NULL );
     159}
     160
     161static void
     162notify_callback( GObject      * source,
     163                 GAsyncResult * res,
     164                 gpointer       user_data )
     165{
     166    TrNotification * n = user_data;
     167    GVariant * result;
     168
     169    result = g_dbus_proxy_call_finish( G_DBUS_PROXY( source ), res, NULL );
     170    if( !result || !g_variant_is_of_type( result, G_VARIANT_TYPE( "(u)" ) ) )
     171    {
     172        if( result )
     173            g_variant_unref( result );
     174        tr_notification_free( n );
     175        return;
     176    }
     177
     178    g_variant_get( result, "(u)", &n->id );
     179    g_hash_table_insert( active_notifications,
     180                         GINT_TO_POINTER( ( int * )&n->id ), n );
     181
     182    g_variant_unref( result );
     183}
    17184
    18185void
    19186gtr_notify_torrent_completed( TrCore * core, int torrent_id )
    20187{
    21     if( gtr_pref_flag_get( PREF_KEY_TORRENT_COMPLETE_SOUND_ENABLED ) )
    22     {
    23         const char * cmd = gtr_pref_string_get( PREF_KEY_TORRENT_COMPLETE_SOUND_COMMAND );
    24         g_spawn_command_line_async( cmd, NULL );
    25     }
    26 
    27     if( gtr_pref_flag_get( PREF_KEY_TORRENT_COMPLETE_NOTIFICATION_ENABLED ) )
    28     {
    29         const tr_torrent * tor = gtr_core_find_torrent( core, torrent_id );
    30         const char * fmt = gtr_pref_string_get( PREF_KEY_TORRENT_COMPLETE_NOTIFICATION_COMMAND );
    31         char * cmd = g_strdup_printf( fmt, _( "Torrent Complete" ), ( tor ? tr_torrentName( tor ) : "" ) );
    32         g_spawn_command_line_async( cmd, NULL );
    33         g_free( cmd );
    34     }
     188    GVariantBuilder actions_builder;
     189    TrNotification * n;
     190    tr_torrent * tor;
     191    const char * cmd = gtr_pref_string_get( PREF_KEY_TORRENT_COMPLETE_SOUND_COMMAND );
     192    g_spawn_command_line_async( cmd, NULL );
     193
     194    if( ! gtr_pref_flag_get( PREF_KEY_TORRENT_COMPLETE_NOTIFICATION_ENABLED ) )
     195        return;
     196
     197    g_return_if_fail( G_IS_DBUS_PROXY( proxy ) );
     198
     199    tor = gtr_core_find_torrent( core, torrent_id );
     200
     201    n = g_new0( TrNotification, 1 );
     202    n->core = g_object_ref( G_OBJECT( core ) );
     203    n->torrent_id = torrent_id;
     204
     205    g_variant_builder_init( &actions_builder, G_VARIANT_TYPE( "as" ) );
     206
     207    if( server_supports_actions )
     208    {
     209        const tr_info * inf = tr_torrentInfo( tor );
     210        if( inf->fileCount == 1 )
     211        {
     212            g_variant_builder_add( &actions_builder, "s", "file" );
     213            g_variant_builder_add( &actions_builder, "s", _( "Open File" ) );
     214        }
     215        else
     216        {
     217            g_variant_builder_add( &actions_builder, "s", "folder" );
     218            g_variant_builder_add( &actions_builder, "s", _( "Open Folder" ) );
     219        }
     220    }
     221
     222    g_dbus_proxy_call( proxy,
     223                       "Notify",
     224                       g_variant_new( "(susssasa{sv}i)",
     225                                      "Transmission", n->id, "transmission",
     226                                      _( "Torrent Complete" ),
     227                                      tr_torrentName( tor ),
     228                                      &actions_builder, NULL, -1 ),
     229                       G_DBUS_CALL_FLAGS_NONE, -1, NULL,
     230                       notify_callback, n );
    35231}
    36232
     
    38234gtr_notify_torrent_added( const char * name )
    39235{
    40     if( gtr_pref_flag_get( PREF_KEY_TORRENT_ADDED_NOTIFICATION_ENABLED ) )
    41     {
    42         const char * fmt = gtr_pref_string_get( PREF_KEY_TORRENT_ADDED_NOTIFICATION_COMMAND );
    43         char * cmd = g_strdup_printf( fmt, _( "Torrent Added" ), name );
    44         g_spawn_command_line_async( cmd, NULL );
    45         g_free( cmd );
    46     }
    47 }
     236    TrNotification * n;
     237
     238    g_return_if_fail( G_IS_DBUS_PROXY( proxy ) );
     239
     240    if( !gtr_pref_flag_get( PREF_KEY_TORRENT_ADDED_NOTIFICATION_ENABLED ) )
     241        return;
     242
     243    n = g_new0( TrNotification, 1 );
     244    g_dbus_proxy_call( proxy,
     245                       "Notify",
     246                       g_variant_new( "(susssasa{sv}i)",
     247                                      "Transmission", 0, "transmission",
     248                                      _( "Torrent Added" ), name,
     249                                      NULL, NULL, -1 ),
     250                       G_DBUS_CALL_FLAGS_NONE, -1, NULL,
     251                       notify_callback, n );
     252}
  • trunk/gtk/notify.h

    r12578 r13107  
    1616#include "tr-core.h"
    1717
     18void gtr_notify_init( void );
     19
    1820void gtr_notify_torrent_added     ( const char * name );
    1921
  • trunk/gtk/tr-prefs.h

    r12682 r13107  
    4343#define PREF_KEY_STATUSBAR_STATS                         "statusbar-stats"
    4444#define PREF_KEY_TOOLBAR                                 "show-toolbar"
    45 #define PREF_KEY_TORRENT_ADDED_NOTIFICATION_COMMAND      "torrent-added-notification-command"
    4645#define PREF_KEY_TORRENT_ADDED_NOTIFICATION_ENABLED      "torrent-added-notification-enabled"
    47 #define PREF_KEY_TORRENT_COMPLETE_NOTIFICATION_COMMAND   "torrent-complete-notification-command"
    4846#define PREF_KEY_TORRENT_COMPLETE_NOTIFICATION_ENABLED   "torrent-complete-notification-enabled"
    4947#define PREF_KEY_TORRENT_COMPLETE_SOUND_COMMAND          "torrent-complete-sound-command"
Note: See TracChangeset for help on using the changeset viewer.