From 37f53760e5a5a2c0f9294c13ca680aaa33af056f Mon Sep 17 00:00:00 2001 From: Alan Fitton Date: Sun, 27 Feb 2011 21:24:43 +0000 Subject: a much better system for suspending tracker/file updates until a change has been acknowledged. fix for issue 17 (bandwidth priorities). use transmission-remote-gtk icon in .desktop instead of transmission. --- configure.ac | 5 ++--- redhat/transmission-remote-gtk.spec | 10 ++++++++- src/requests.c | 10 ++++----- src/requests.h | 10 ++++----- src/transmission-remote-gtk.desktop.in | 2 +- src/trg-files-model.c | 16 +++++++-------- src/trg-files-model.h | 4 ++-- src/trg-files-tree-view.c | 22 ++++++++++++++++---- src/trg-main-window.c | 26 +++++++++++++++--------- src/trg-torrent-props-dialog.c | 2 +- src/trg-trackers-model.c | 15 +++++++------- src/trg-trackers-model.h | 7 ++----- src/trg-trackers-tree-view.c | 37 +++++++++++++++++++--------------- 13 files changed, 96 insertions(+), 70 deletions(-) diff --git a/configure.ac b/configure.ac index a31ef65..4d4f41c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,5 @@ -#AC_PREREQ([2.65]) -AC_INIT(transmission-remote-gtk, 0.2.1, alan@eth0.org.uk) -AM_INIT_AUTOMAKE(transmission-remote-gtk, 0.2.1) +AC_INIT(transmission-remote-gtk, 0.2.2, alan@eth0.org.uk) +AM_INIT_AUTOMAKE(transmission-remote-gtk, 0.2.2) AC_OUTPUT(Makefile src/Makefile) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) diff --git a/redhat/transmission-remote-gtk.spec b/redhat/transmission-remote-gtk.spec index 178951e..742083d 100644 --- a/redhat/transmission-remote-gtk.spec +++ b/redhat/transmission-remote-gtk.spec @@ -1,5 +1,5 @@ Name: transmission-remote-gtk -Version: 0.2.1 +Version: 0.2.2 Release: 1%{?dist:%{dist}} Summary: Remote control client for Transmission BitTorrent @@ -89,6 +89,14 @@ fi %{_datadir}/icons/hicolor/48x48/apps/transmission-remote-gtk.png %changelog +* Sun Feb 27 2011 Alan Fitton - 0.2.2 +- Put versions in some spec/configure deps. +- Include libcurl.m4. +- Better (easier) FreeBSD compilation. +- Remove 5px window border (much better on some dark themes). +- Fix hardcoded path to Transmission icon in about dialog. +- Fix a leak from gtk_tree_selection_get_selected_rows(). + * Mon Feb 21 2011 Alan Fitton - 0.2.1 - Fix crash in update-blocklist/port-test callbacks. - Menu bar mnemonics. diff --git a/src/requests.c b/src/requests.c index 8687f6b..ceba326 100644 --- a/src/requests.c +++ b/src/requests.c @@ -40,22 +40,22 @@ JsonNode *generic_request(gchar * method, JsonArray * ids) return root; } -JsonNode *session_stats() +JsonNode *session_stats(void) { return generic_request(METHOD_SESSION_STATS, NULL); } -JsonNode *blocklist_update() +JsonNode *blocklist_update(void) { return generic_request(METHOD_BLOCKLIST_UPDATE, NULL); } -JsonNode *port_test() +JsonNode *port_test(void) { return generic_request(METHOD_PORT_TEST, NULL); } -JsonNode *session_get() +JsonNode *session_get(void) { return generic_request(METHOD_SESSION_GET, NULL); } @@ -110,7 +110,7 @@ JsonNode *torrent_remove(JsonArray * array, gboolean removeData) return root; } -JsonNode *torrent_get() +JsonNode *torrent_get(void) { JsonNode *root = base_request(METHOD_TORRENT_GET); JsonArray *fields = json_array_new(); diff --git a/src/requests.h b/src/requests.h index 99c99b8..5a1b771 100644 --- a/src/requests.h +++ b/src/requests.h @@ -26,8 +26,8 @@ JsonNode *generic_request(gchar * method, JsonArray * array); JsonNode *session_set(void); -JsonNode *session_get(); -JsonNode *torrent_get(); +JsonNode *session_get(void); +JsonNode *torrent_get(void); JsonNode *torrent_set(JsonArray * array); JsonNode *torrent_pause(JsonArray * array); JsonNode *torrent_start(JsonArray * array); @@ -38,8 +38,8 @@ JsonNode *torrent_add(gchar * filename, gboolean paused); JsonNode *torrent_add_url(const gchar * url, gboolean paused); JsonNode *torrent_set_location(JsonArray * array, gchar * location, gboolean move); -JsonNode *blocklist_update(); -JsonNode *port_test(); -JsonNode *session_stats(); +JsonNode *blocklist_update(void); +JsonNode *port_test(void); +JsonNode *session_stats(void); #endif /* REQUESTS_H_ */ diff --git a/src/transmission-remote-gtk.desktop.in b/src/transmission-remote-gtk.desktop.in index 3edeb63..c518695 100644 --- a/src/transmission-remote-gtk.desktop.in +++ b/src/transmission-remote-gtk.desktop.in @@ -4,7 +4,7 @@ GenericName=Remote BitTorrent Client X-GNOME-FullName=Transmission BitTorrent Remote Control Comment=Remotely control Transmission BitTorrent client Exec=@bindir@/transmission-remote-gtk %F -Icon=transmission +Icon=transmission-remote-gtk Terminal=false TryExec=transmission-remote-gtk Type=Application diff --git a/src/trg-files-model.c b/src/trg-files-model.c index 9afc4cc..3f2458d 100644 --- a/src/trg-files-model.c +++ b/src/trg-files-model.c @@ -37,8 +37,7 @@ struct _TrgFilesModelPrivate { JsonArray *files; JsonArray *wanted; JsonArray *priorities; - gint64 updateBarrier; - gint64 currentSerial; + gboolean accept; }; static void trg_files_model_iter_new(TrgFilesModel * model, @@ -55,11 +54,11 @@ static void trg_files_model_iter_new(TrgFilesModel * model, FILESCOL_SIZE, size, FILESCOL_ID, id, -1); } -void trg_files_model_set_update_barrier(TrgFilesModel * model, - gint64 serial) +void trg_files_model_set_accept(TrgFilesModel * model, + gboolean accept) { TrgFilesModelPrivate *priv = TRG_FILES_MODEL_GET_PRIVATE(model); - priv->updateBarrier = serial; + priv->accept = accept; } static void @@ -79,8 +78,7 @@ trg_files_model_iter_update(TrgFilesModel * model, gtk_list_store_set(GTK_LIST_STORE(model), filesIter, FILESCOL_PROGRESS, progress, -1); - if (priv->updateBarrier < 0 - || priv->currentSerial > priv->updateBarrier) { + if (priv->accept) { gtk_list_store_set(GTK_LIST_STORE(model), filesIter, FILESCOL_ICON, wanted ? GTK_STOCK_FILE : @@ -99,7 +97,7 @@ static void trg_files_model_init(TrgFilesModel * self) TrgFilesModelPrivate *priv = TRG_FILES_MODEL_GET_PRIVATE(self); GType column_types[FILESCOL_COLUMNS]; - priv->updateBarrier = -1; + priv->accept = TRUE; column_types[FILESCOL_ICON] = G_TYPE_STRING; column_types[FILESCOL_NAME] = G_TYPE_STRING; @@ -146,9 +144,9 @@ trg_files_model_update(TrgFilesModel * model, gint64 updateSerial, priv->priorities = torrent_get_priorities(t); priv->wanted = torrent_get_wanted(t); priv->files = torrent_get_files(t); - priv->currentSerial = updateSerial; if (first == TRUE) { + priv->accept = TRUE; for (j = 0; j < json_array_get_length(priv->files); j++) { JsonObject *file = json_node_get_object(json_array_get_element diff --git a/src/trg-files-model.h b/src/trg-files-model.h index 7c5a296..5871120 100644 --- a/src/trg-files-model.h +++ b/src/trg-files-model.h @@ -68,7 +68,7 @@ void trg_files_model_update(TrgFilesModel * model, gint64 updateSerial, JsonObject * t, gboolean first); gint64 trg_files_model_get_torrent_id(TrgFilesModel * model); -void trg_files_model_set_update_barrier(TrgFilesModel * model, - gint64 serial); +void trg_files_model_set_accept(TrgFilesModel * model, + gboolean accept); #endif /* TRG_FILES_MODEL_H_ */ diff --git a/src/trg-files-tree-view.c b/src/trg-files-tree-view.c index de947e8..b65c636 100644 --- a/src/trg-files-tree-view.c +++ b/src/trg-files-tree-view.c @@ -135,6 +135,19 @@ static void remove_array_if_empty(JsonObject * args, gchar * key) json_object_remove_member(args, key); } +static void +on_files_update(JsonObject * response, int status, + gpointer data) +{ + TrgFilesTreeViewPrivate *priv = TRG_FILES_TREE_VIEW_GET_PRIVATE(data); + GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(data)); + + trg_files_model_set_accept(TRG_FILES_MODEL(model), + TRUE); + + on_generic_interactive_action(response, status, priv->win); +} + static void send_updated_file_prefs(TrgFilesTreeView * tv) { TrgFilesTreeViewPrivate *priv = TRG_FILES_TREE_VIEW_GET_PRIVATE(tv); @@ -175,10 +188,11 @@ static void send_updated_file_prefs(TrgFilesTreeView * tv) remove_array_if_empty(args, FIELD_FILES_PRIORITY_NORMAL); remove_array_if_empty(args, FIELD_FILES_PRIORITY_LOW); - trg_files_model_set_update_barrier(TRG_FILES_MODEL(model), - priv->client->updateSerial + 1); - dispatch_async(priv->client, req, on_generic_interactive_action, - priv->win); + trg_files_model_set_accept(TRG_FILES_MODEL(model), + FALSE); + + dispatch_async(priv->client, req, on_files_update, + tv); } static void set_low(GtkWidget * w G_GNUC_UNUSED, gpointer data) diff --git a/src/trg-main-window.c b/src/trg-main-window.c index 496add9..db0db2a 100644 --- a/src/trg-main-window.c +++ b/src/trg-main-window.c @@ -1024,9 +1024,17 @@ void on_generic_interactive_action(JsonObject * response, int status, gpointer data) { - gdk_threads_enter(); - trg_dialog_error_handler(TRG_MAIN_WINDOW(data), response, status); - gdk_threads_leave(); + TrgMainWindowPrivate *priv = TRG_MAIN_WINDOW_GET_PRIVATE(data); + + if (priv->client->session != NULL) + { + gdk_threads_enter(); + trg_dialog_error_handler(TRG_MAIN_WINDOW(data), response, status); + gdk_threads_leave(); + + if (status == CURLE_OK || status == FAIL_RESPONSE_UNSUCCESSFUL) + dispatch_async(priv->client, torrent_get(), on_torrent_get, data); + } response_unref(response); } @@ -1053,15 +1061,15 @@ on_torrent_get_multipurpose(JsonObject * response, gboolean first, priv = TRG_MAIN_WINDOW_GET_PRIVATE(data); client = priv->client; - gdk_threads_enter(); - /* Disconnected between request and response callback */ if (client->session == NULL) { - gdk_threads_leave(); response_unref(response); return; } + g_mutex_lock(client->updateMutex); + gdk_threads_enter(); + if (status != CURLE_OK) { client->failCount++; if (client->failCount >= 3) { @@ -1084,6 +1092,7 @@ on_torrent_get_multipurpose(JsonObject * response, gboolean first, trg_update_torrents_timerfunc, data); } gdk_threads_leave(); + g_mutex_unlock(client->updateMutex); response_unref(response); return; } @@ -1095,8 +1104,6 @@ on_torrent_get_multipurpose(JsonObject * response, gboolean first, stats.down = 0; stats.paused = 0; - g_mutex_lock(client->updateMutex); - client->updateSerial++; trg_torrent_model_update(priv->torrentModel, priv->client, @@ -1104,14 +1111,13 @@ on_torrent_get_multipurpose(JsonObject * response, gboolean first, update_selected_torrent_notebook(TRG_MAIN_WINDOW(data), first); - g_mutex_unlock(client->updateMutex); - trg_status_bar_update(priv->statusBar, &stats); g_timeout_add_seconds(client->interval, trg_update_torrents_timerfunc, data); gdk_threads_leave(); + g_mutex_unlock(client->updateMutex); response_unref(response); } diff --git a/src/trg-torrent-props-dialog.c b/src/trg-torrent-props-dialog.c index 266360e..ab59120 100644 --- a/src/trg-torrent-props-dialog.c +++ b/src/trg-torrent-props-dialog.c @@ -143,7 +143,7 @@ trg_torrent_props_response_cb(GtkDialog * dlg, gint res_id, gtk_combo_box_get_active(GTK_COMBO_BOX (priv-> bandwidthPriorityCombo)) - + 1); + - 1); gtk_spin_button_json_int_out(GTK_SPIN_BUTTON (priv->peer_limit_spin), args); diff --git a/src/trg-trackers-model.c b/src/trg-trackers-model.c index 6e2a888..dcdec45 100644 --- a/src/trg-trackers-model.c +++ b/src/trg-trackers-model.c @@ -32,7 +32,7 @@ typedef struct _TrgTrackersModelPrivate TrgTrackersModelPrivate; struct _TrgTrackersModelPrivate { gint64 torrentId; - gint64 updateBarrier; + gint64 accept; }; void trg_trackers_model_set_no_selection(TrgTrackersModel * model) @@ -61,9 +61,8 @@ void trg_trackers_model_update(TrgTrackersModel * model, if (first) { gtk_list_store_clear(GTK_LIST_STORE(model)); priv->torrentId = torrent_get_id(t); - } else if (priv->updateBarrier == TRACKERS_UPDATE_BARRIER_FULL - || (priv->updateBarrier >= 0 - && priv->updateBarrier > updateSerial)) { + accept = TRUE; + } else if (!priv->accept) { return; } @@ -118,11 +117,11 @@ static void trg_trackers_model_class_init(TrgTrackersModelClass * klass) g_type_class_add_private(klass, sizeof(TrgTrackersModelPrivate)); } -void trg_trackers_model_set_update_barrier(TrgTrackersModel * model, - gint64 barrier) +void trg_trackers_model_set_accept(TrgTrackersModel * model, + gboolean accept) { TrgTrackersModelPrivate *priv = TRG_TRACKERS_MODEL_GET_PRIVATE(model); - priv->updateBarrier = barrier; + priv->accept = accept; } static void trg_trackers_model_init(TrgTrackersModel * self) @@ -138,7 +137,7 @@ static void trg_trackers_model_init(TrgTrackersModel * self) column_types[TRACKERCOL_ID] = G_TYPE_INT64; column_types[TRACKERCOL_UPDATESERIAL] = G_TYPE_INT64; - priv->updateBarrier = TRACKERS_UPDATE_BARRIER_NONE; + priv->accept = TRUE; priv->torrentId = -1; gtk_list_store_set_column_types(GTK_LIST_STORE(self), diff --git a/src/trg-trackers-model.h b/src/trg-trackers-model.h index ab60eff..763b419 100644 --- a/src/trg-trackers-model.h +++ b/src/trg-trackers-model.h @@ -23,9 +23,6 @@ #include #include -#define TRACKERS_UPDATE_BARRIER_NONE -1 -#define TRACKERS_UPDATE_BARRIER_FULL -2 - G_BEGIN_DECLS #define TRG_TYPE_TRACKERS_MODEL trg_trackers_model_get_type() #define TRG_TRACKERS_MODEL(obj) \ @@ -54,8 +51,8 @@ G_END_DECLS void trg_trackers_model_update(TrgTrackersModel * model, gint64 updateSerial, JsonObject * t, gboolean first); -void trg_trackers_model_set_update_barrier(TrgTrackersModel * model, - gint64 serial); +void trg_trackers_model_set_accept(TrgTrackersModel * model, + gboolean accept); gint64 trg_trackers_model_get_torrent_id(TrgTrackersModel * model); void trg_trackers_model_set_no_selection(TrgTrackersModel * model); diff --git a/src/trg-trackers-tree-view.c b/src/trg-trackers-tree-view.c index c0f45b2..c7bb101 100644 --- a/src/trg-trackers-tree-view.c +++ b/src/trg-trackers-tree-view.c @@ -48,6 +48,19 @@ trg_trackers_tree_view_class_init(TrgTrackersTreeViewClass * klass) g_type_class_add_private(klass, sizeof(TrgTrackersTreeViewPrivate)); } +static void +on_trackers_update(JsonObject * response, int status, + gpointer data) +{ + TrgTrackersTreeViewPrivate *priv = TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(data); + GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(data)); + + trg_trackers_model_set_accept(TRG_TRACKERS_MODEL(model), + TRUE); + + on_generic_interactive_action(response, status, priv->win); +} + void trg_trackers_tree_view_new_connection(TrgTrackersTreeView * tv, trg_client * tc) { @@ -104,11 +117,8 @@ static void trg_tracker_announce_edited(GtkCellRendererText * renderer, g_free(icon); - trg_trackers_model_set_update_barrier(TRG_TRACKERS_MODEL(model), - priv->client->updateSerial + 1); - - dispatch_async(priv->client, req, on_generic_interactive_action, - priv->win); + dispatch_async(priv->client, req, on_trackers_update, + user_data); } static void trg_tracker_announce_editing_started(GtkCellRenderer * @@ -120,20 +130,17 @@ static void trg_tracker_announce_editing_started(GtkCellRenderer * TrgTrackersModel *model = TRG_TRACKERS_MODEL(gtk_tree_view_get_model (GTK_TREE_VIEW(user_data))); - trg_trackers_model_set_update_barrier(model, - TRACKERS_UPDATE_BARRIER_FULL); + + trg_trackers_model_set_accept(model, FALSE); } static void trg_tracker_announce_editing_canceled(GtkWidget * w, gpointer data) { - TrgTrackersTreeViewPrivate *priv = - TRG_TRACKERS_TREE_VIEW_GET_PRIVATE(data); TrgTrackersModel *model = TRG_TRACKERS_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(data))); - trg_trackers_model_set_update_barrier(model, - priv->client->updateSerial + 1); + trg_trackers_model_set_accept(model, TRUE); } static void trg_trackers_tree_view_init(TrgTrackersTreeView * self) @@ -226,11 +233,9 @@ static void delete_tracker(GtkWidget * w, gpointer data) json_object_set_array_member(args, "trackerRemove", trackerIds); - trg_trackers_model_set_update_barrier(TRG_TRACKERS_MODEL(model), - priv->client->updateSerial + 1); + trg_trackers_model_set_accept(TRG_TRACKERS_MODEL(model), FALSE); - dispatch_async(priv->client, req, on_generic_interactive_action, - priv->win); + dispatch_async(priv->client, req, on_trackers_update, data); } static void @@ -310,10 +315,10 @@ view_onButtonPressed(GtkWidget * treeview, GdkEventButton * event, gtk_tree_path_free(path); view_popup_menu(treeview, event, userdata); - return TRUE; } else if (trg_trackers_model_get_torrent_id(model) >= 0) { view_popup_menu_add_only(treeview, event, userdata); } + return TRUE; } return FALSE; -- cgit v1.2.3