From 2a98c847ba99c2819f2df62187bafd79094734e9 Mon Sep 17 00:00:00 2001 From: Simon the Sorcerer Date: Tue, 26 Dec 2017 12:40:24 +0100 Subject: added xfce-base/thunar with queued file transfer patch. --- xfce-base/thunar/Manifest | 5 + .../files/thunar-1.16.2-integer-overflow.patch | 29 + .../files/thunar-queuedtransfer-20160702.patch | 721 +++++++++++++++++++++ xfce-base/thunar/metadata.xml | 12 + xfce-base/thunar/thunar-1.6.13_p1.ebuild | 83 +++ 5 files changed, 850 insertions(+) create mode 100644 xfce-base/thunar/Manifest create mode 100644 xfce-base/thunar/files/thunar-1.16.2-integer-overflow.patch create mode 100644 xfce-base/thunar/files/thunar-queuedtransfer-20160702.patch create mode 100644 xfce-base/thunar/metadata.xml create mode 100644 xfce-base/thunar/thunar-1.6.13_p1.ebuild diff --git a/xfce-base/thunar/Manifest b/xfce-base/thunar/Manifest new file mode 100644 index 0000000..c8d9696 --- /dev/null +++ b/xfce-base/thunar/Manifest @@ -0,0 +1,5 @@ +AUX thunar-1.16.2-integer-overflow.patch 1160 SHA256 e88ceeefc3a93ac44b95684febd2816be59adc813df1b1e1c7c10a1023b88a9b SHA512 eaefb709e03902cc97be41d4c670ded910234fd1536aae8597cbd9224e0d61badfee912eba81ee2e1a6c308ccd12b26961634e24b8b64fc8457b9d31ba57a843 WHIRLPOOL 89736ac87f23180871c6d316575036037ba083d8ba0119687596e40bc0f527f1ff43dadc5d820c9a69e8838951db307705b87474057b4b53d937916496582d50 +AUX thunar-queuedtransfer-20160702.patch 29353 SHA256 a31507e15fdcd3a869d3680fb0f72d0d9f5bcddbfa1affff15faf4441041fb6d SHA512 a5fd11c7d58082ddce0895020ef8aff5e243400d7343d60af99e01b7aa65ddd3fdc7a61287201022b1598460bc1ee6f08da8d4e7027769e2fdf081197ed8bfec WHIRLPOOL 202944871672b16805085e7cab75926900b4d7def63617c3aa244858b7ef1d99020299877041f0ca0da580e29a0001b03d45f7f494cbaba83c332430c67759b3 +DIST Thunar-1.6.13.tar.bz2 1937341 SHA256 a2900acfa92f965aff86cd7728d88a3836b3d21fb85d3355a8c5119c9975f93f SHA512 d1ae8efd0652c21b14ff45be9eef2ccf6b4400c744b08b2096a47b1af4eade2df1a237d03ede3e5dccea018b626dd67ffda2ed946b31fc2d3ff214c79e30168f WHIRLPOOL 7b7debc04d298ce1575924ee01fef45341f7fc63020985e3d68790ded03bbe3e501d6e072b077f388b6e8d70c38cb6ef3ece0d1a1a85c998312cf8e8b097900b +EBUILD thunar-1.6.13_p1.ebuild 2131 SHA256 0fc72f7a6d7e7e128259812fe98ca818779edc3a6e0c03a56ce81e97837ac9b0 SHA512 33d2a28fa2909a8fdd39e9f4e2c1d0a0de63130f70c88b3ffeca12b69a399c6e3062aa58853bf55a0b541fa37e54e9eaa4a8093b806896bc3fecd166c024ffe3 WHIRLPOOL a92fdcb32096969fcdb25c5fdff8fddf8a9d273ea798458184f7c5a3252f1d3abca6bdc39084fadacca99665b7a889477ea353e134215e5acad911ddcdab739d +MISC metadata.xml 372 SHA256 c79517f1436518a816ff7335e5e342411b5ce9a2e1ef2279ecc60c4d5e2fa233 SHA512 3ecb379e314ff3f9c745b61707c6df0a912b1466bd56abeebdba0ee138e14ee331fcd61acb3c5b64ace4daa42cbaaec8331cc83d6ae5d0bdc1fa5a69a258ef17 WHIRLPOOL 67ce77734c8d88994c73eee383689f0e6ed7fc2dfe936b3866ec52cb791b6b1d9ac7eaf9871ac6617c507b73738ded310a3a35eb1772ec307b3802e9dc5a6ac6 diff --git a/xfce-base/thunar/files/thunar-1.16.2-integer-overflow.patch b/xfce-base/thunar/files/thunar-1.16.2-integer-overflow.patch new file mode 100644 index 0000000..09f4b93 --- /dev/null +++ b/xfce-base/thunar/files/thunar-1.16.2-integer-overflow.patch @@ -0,0 +1,29 @@ +From 1736b1f69ecf3e44a1b957d8090fb04c6bc5fd95 Mon Sep 17 00:00:00 2001 +From: Mikhail Efremov +Date: Thu, 11 Feb 2016 18:59:27 +0300 +Subject: [PATCH] Fix potential buffer overflow + +Use g_malloc_n() instead of g_malloc to avoid integer overflow. +This fixes CVE-2013-7447, see +http://www.openwall.com/lists/oss-security/2016/02/10/2 +for details. +--- + thunar/thunar-gdk-extensions.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/thunar/thunar-gdk-extensions.c b/thunar/thunar-gdk-extensions.c +index 50ecb4a..775eca3 100644 +--- a/thunar/thunar-gdk-extensions.c ++++ b/thunar/thunar-gdk-extensions.c +@@ -75,7 +75,7 @@ thunar_gdk_cairo_create_surface (const GdkPixbuf *pixbuf) + + /* prepare pixel data and surface */ + cairo_stride = cairo_format_stride_for_width (format, width); +- cairo_pixels = g_malloc (height * cairo_stride); ++ cairo_pixels = g_malloc_n (height, cairo_stride); + surface = cairo_image_surface_create_for_data (cairo_pixels, format, + width, height, cairo_stride); + cairo_surface_set_user_data (surface, &cairo_key, cairo_pixels, g_free); +-- +2.6.5 + diff --git a/xfce-base/thunar/files/thunar-queuedtransfer-20160702.patch b/xfce-base/thunar/files/thunar-queuedtransfer-20160702.patch new file mode 100644 index 0000000..3cbccee --- /dev/null +++ b/xfce-base/thunar/files/thunar-queuedtransfer-20160702.patch @@ -0,0 +1,721 @@ +From 50c67c23cd9bfeb0bb4f0cdd5b5ec614c850c8bd Mon Sep 17 00:00:00 2001 +From: Cyrille Pontvieux +Date: Wed, 29 Jun 2016 05:43:26 +0200 +Subject: Simultaneous or queued copies +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When a new copy process occurs and another copy process exists, +the source devices and target devices are compared. +If one match (either source or target), then the files are appended to +the currently running copy process instead of trying to simultaneous +copy them. +Some thresholds are defined though: +- 100 MB minumum for the new copy process, if less, the copy is done +aside. +- 10 seconds minimum of estimated remaining time for the running copy +process. +One can change some settings using three preferences: +- Simultaneous max file copies (0 for ∞, default value) +- Copying files from same devices behavior: + - Ask everytime + - Copy simultaneously (default value) + - Queue files +- Copying files to same devices behavior: same values as "from" + +The default behavior is the same as the current Thunar. +--- + thunar/thunar-enum-types.c | 23 + + thunar/thunar-enum-types.h | 20 + + thunar/thunar-job.c | 24 + + thunar/thunar-job.h | 3 + + thunar/thunar-preferences-dialog.c | 57 ++ + thunar/thunar-preferences.c | 46 ++ + thunar/thunar-transfer-job.c | 333 +++++++++- + 7 files changed, 1221 insertions(+), 510 deletions(-) + +diff --git a/thunar/thunar-enum-types.c b/thunar/thunar-enum-types.c +index 479bbcf..d97128e 100644 +--- a/thunar/thunar-enum-types.c ++++ b/thunar/thunar-enum-types.c +@@ -162,6 +162,29 @@ thunar_recursive_permissions_get_type (void) + + + GType ++thunar_copy_same_device_get_type (void) ++{ ++ static GType type = G_TYPE_INVALID; ++ ++ if (G_UNLIKELY (type == G_TYPE_INVALID)) ++ { ++ static const GEnumValue values[] = ++ { ++ { THUNAR_COPY_SAME_DEVICE_ASK, "THUNAR_COPY_SAME_DEVICE_ASK", "ask", }, ++ { THUNAR_COPY_SAME_DEVICE_SIMULTANEOUSLY, "THUNAR_COPY_SAME_DEVICE_SIMULTANEOUSLY", "simultaneous", }, ++ { THUNAR_COPY_SAME_DEVICE_QUEUE, "THUNAR_COPY_SAME_DEVICE_QUEUE", "queue", }, ++ { 0, NULL, NULL, }, ++ }; ++ ++ type = g_enum_register_static (I_("ThunarCopySameDeviceMode"), values); ++ } ++ ++ return type; ++} ++ ++ ++ ++GType + thunar_zoom_level_get_type (void) + { + static GType type = G_TYPE_INVALID; +diff --git a/thunar/thunar-enum-types.h b/thunar/thunar-enum-types.h +index 9fb34a7..8d293b3 100644 +--- a/thunar/thunar-enum-types.h ++++ b/thunar/thunar-enum-types.h +@@ -180,6 +180,26 @@ typedef enum + GType thunar_recursive_permissions_get_type (void) G_GNUC_CONST; + + ++#define THUNAR_TYPE_COPY_SAME_DEVICE (thunar_copy_same_device_get_type ()) ++ ++/** ++ * ThunarCopySameDeviceMode: ++ * @THUNAR_COPY_SAME_DEVICE_ASK : ask the user for simultaneous copy (or not) everytime a copy is done using a same device. ++ * @THUNAR_COPY_SAME_DEVICE_SIMULTANEOUSLY : always copy simultaneously when using a same device (if not max simultaneous copies reached). ++ * @THUNAR_COPY_SAME_DEVICE_QUEUE : always queue the copy when using a same device. ++ * ++ * Modus operandi when copying using a same device. ++ **/ ++typedef enum ++{ ++ THUNAR_COPY_SAME_DEVICE_ASK, ++ THUNAR_COPY_SAME_DEVICE_SIMULTANEOUSLY, ++ THUNAR_COPY_SAME_DEVICE_QUEUE, ++} ThunarCopySameDeviceMode; ++ ++GType thunar_copy_same_device_get_type (void) G_GNUC_CONST; ++ ++ + #define THUNAR_TYPE_ZOOM_LEVEL (thunar_zoom_level_get_type ()) + + /** +diff --git a/thunar/thunar-job.c b/thunar/thunar-job.c +index f4ce28e..d692f0d 100644 +--- a/thunar/thunar-job.c ++++ b/thunar/thunar-job.c +@@ -546,6 +546,30 @@ thunar_job_ask_no_size (ThunarJob *job, + + + ++ThunarJobResponse ++thunar_job_ask_queue_copy (ThunarJob *job, ++ const gchar *format, ++ ...) ++{ ++ ThunarJobResponse response; ++ va_list var_args; ++ _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL); ++ _thunar_return_val_if_fail (format != NULL, THUNAR_JOB_RESPONSE_CANCEL); ++ /* check if the user already cancelled the job */ ++ if (G_UNLIKELY (exo_job_is_cancelled (EXO_JOB (job)))) ++ return THUNAR_JOB_RESPONSE_CANCEL; ++ /* ask the user what he wants to do */ ++ va_start (var_args, format); ++ response = _thunar_job_ask_valist (job, format, var_args, ++ _("Do you want to queue this copy?"), ++ THUNAR_JOB_RESPONSE_YES ++ | THUNAR_JOB_RESPONSE_NO); ++ va_end (var_args); ++ return response; ++} ++ ++ ++ + gboolean + thunar_job_files_ready (ThunarJob *job, + GList *file_list) +diff --git a/thunar/thunar-job.h b/thunar/thunar-job.h +index f1f636b..f1372ed 100644 +--- a/thunar/thunar-job.h ++++ b/thunar/thunar-job.h +@@ -84,6 +84,9 @@ ThunarJobResponse thunar_job_ask_replace (ThunarJob *job, + ThunarJobResponse thunar_job_ask_skip (ThunarJob *job, + const gchar *format, + ...); ++ThunarJobResponse thunar_job_ask_queue_copy (ThunarJob *job, ++ const gchar *format, ++ ...); + gboolean thunar_job_ask_no_size (ThunarJob *job, + const gchar *format, + ...); +diff --git a/thunar/thunar-preferences-dialog.c b/thunar/thunar-preferences-dialog.c +index 057766e..8db1e56 100644 +--- a/thunar/thunar-preferences-dialog.c ++++ b/thunar/thunar-preferences-dialog.c +@@ -206,6 +206,7 @@ thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog) + GtkWidget *button; + GtkWidget *align; + GtkWidget *combo; ++ GtkWidget *spinbutton; + GtkWidget *frame; + GtkWidget *label; + GtkWidget *range; +@@ -626,6 +627,62 @@ thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog) + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0); + gtk_widget_show (frame); + ++ label = gtk_label_new (_("Simultaneous file copies")); ++ gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_bold ()); ++ gtk_frame_set_label_widget (GTK_FRAME (frame), label); ++ gtk_widget_show (label); ++ ++ table = gtk_table_new (3, 2, FALSE); ++ gtk_table_set_row_spacings (GTK_TABLE (table), 6); ++ gtk_table_set_col_spacings (GTK_TABLE (table), 12); ++ gtk_container_set_border_width (GTK_CONTAINER (table), 12); ++ gtk_container_add (GTK_CONTAINER (frame), table); ++ gtk_widget_show (table); ++ ++ label = gtk_label_new_with_mnemonic (_("Simultaneous _max file copies:")); ++ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); ++ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); ++ gtk_widget_show (label); ++ ++ spinbutton = gtk_spin_button_new_with_range (0, 100, 1); ++ exo_mutual_binding_new (G_OBJECT (dialog->preferences), "misc-max-simultaneous-copies", G_OBJECT (spinbutton), "value"); ++ gtk_table_attach (GTK_TABLE (table), spinbutton, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); ++ thunar_gtk_label_set_a11y_relation (GTK_LABEL (label), spinbutton); ++ gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinbutton); ++ gtk_widget_show (spinbutton); ++ ++ label = gtk_label_new_with_mnemonic (_("Copying files _from same devices:")); ++ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); ++ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0); ++ gtk_widget_show (label); ++ ++ combo = gtk_combo_box_text_new (); ++ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("Ask everytime")); ++ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("Copy simultaneously")); ++ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("Queue files")); ++ exo_mutual_binding_new (G_OBJECT (dialog->preferences), "misc-copy-from-same-device", G_OBJECT (combo), "active"); ++ gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); ++ thunar_gtk_label_set_a11y_relation (GTK_LABEL (label), combo); ++ gtk_widget_show (combo); ++ ++ label = gtk_label_new_with_mnemonic (_("Copying files _to same devices:")); ++ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); ++ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 0, 0); ++ gtk_widget_show (label); ++ ++ combo = gtk_combo_box_text_new (); ++ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("Ask everytime")); ++ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("Copy simultaneously")); ++ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("Queue files")); ++ exo_mutual_binding_new (G_OBJECT (dialog->preferences), "misc-copy-to-same-device", G_OBJECT (combo), "active"); ++ gtk_table_attach (GTK_TABLE (table), combo, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); ++ thunar_gtk_label_set_a11y_relation (GTK_LABEL (label), combo); ++ gtk_widget_show (combo); ++ ++ frame = g_object_new (GTK_TYPE_FRAME, "border-width", 0, "shadow-type", GTK_SHADOW_NONE, NULL); ++ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0); ++ gtk_widget_show (frame); ++ + label = gtk_label_new (_("Volume Management")); + gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_bold ()); + gtk_frame_set_label_widget (GTK_FRAME (frame), label); +diff --git a/thunar/thunar-preferences.c b/thunar/thunar-preferences.c +index 9a86ae1..8db7ac3 100644 +--- a/thunar/thunar-preferences.c ++++ b/thunar/thunar-preferences.c +@@ -82,6 +82,9 @@ enum + PROP_MISC_IMAGE_SIZE_IN_STATUSBAR, + PROP_MISC_MIDDLE_CLICK_IN_TAB, + PROP_MISC_RECURSIVE_PERMISSIONS, ++ PROP_MISC_MAX_SIMULTANEOUS_COPIES, ++ PROP_MISC_COPY_FROM_SAME_DEVICE, ++ PROP_MISC_COPY_TO_SAME_DEVICE, + PROP_MISC_REMEMBER_GEOMETRY, + PROP_MISC_SHOW_ABOUT_TEMPLATES, + PROP_MISC_SINGLE_CLICK, +@@ -587,6 +590,49 @@ thunar_preferences_class_init (ThunarPreferencesClass *klass) + EXO_PARAM_READWRITE); + + /** ++ * ThunarPreferences:misc-max-simultaneous-copies: ++ * ++ * Max number of simultaneous file copies than can occur. ++ * 0 means infinite (default value) ++ * When the max number occurs, any new copy will be appended ++ * to the last running copy. ++ **/ ++ preferences_props[PROP_MISC_MAX_SIMULTANEOUS_COPIES] = ++ g_param_spec_uint ("misc-max-simultaneous-copies", ++ "MiscMaxSimultaneousCopies", ++ NULL, ++ 0, ++ 100, ++ 0, ++ EXO_PARAM_READWRITE); ++ ++ /** ++ * ThunarPreferences:misc-copy-from-same-device: ++ * ++ * Specify what to do when copying files from the same device. ++ **/ ++ preferences_props[PROP_MISC_COPY_FROM_SAME_DEVICE] = ++ g_param_spec_enum ("misc-copy-from-same-device", ++ "MiscCopyFromSameDevice", ++ NULL, ++ THUNAR_TYPE_COPY_SAME_DEVICE, ++ THUNAR_COPY_SAME_DEVICE_SIMULTANEOUSLY, ++ EXO_PARAM_READWRITE); ++ ++ /** ++ * ThunarPreferences:misc-copy-to-same-device: ++ * ++ * Specify what to do when copying files to the same device. ++ **/ ++ preferences_props[PROP_MISC_COPY_TO_SAME_DEVICE] = ++ g_param_spec_enum ("misc-copy-to-same-device", ++ "MiscCopyToSameDevice", ++ NULL, ++ THUNAR_TYPE_COPY_SAME_DEVICE, ++ THUNAR_COPY_SAME_DEVICE_SIMULTANEOUSLY, ++ EXO_PARAM_READWRITE); ++ ++ /** + * ThunarPreferences:misc-remember-geometry: + * + * Whether Thunar should remember the size of windows and apply +diff --git a/thunar/thunar-transfer-job.c b/thunar/thunar-transfer-job.c +index 82482e0..a432c93 100644 +--- a/thunar/thunar-transfer-job.c ++++ b/thunar/thunar-transfer-job.c +@@ -26,6 +26,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -39,7 +40,9 @@ + + /* seconds before we show the transfer rate + remaining time */ + #define MINIMUM_TRANSFER_TIME (10 * G_USEC_PER_SEC) /* 10 seconds */ +- ++/* minimum size (in bytes) for one job to be queued in another */ ++#define QUEUE_MIN_SIZE (100 * 1024 * 1024) /* 100 MB */ ++#define QUEUE_MIN_SEC 10 + + + /* Property identifiers */ +@@ -47,6 +50,9 @@ enum + { + PROP_0, + PROP_FILE_SIZE_BINARY, ++ PROP_MAX_SIMULTANEOUS_COPIES, ++ PROP_COPY_FROM_SAME_DEVICE, ++ PROP_COPY_TO_SAME_DEVICE, + }; + + +@@ -84,6 +90,7 @@ struct _ThunarTransferJob + ThunarTransferJobType type; + GList *source_node_list; + GList *target_file_list; ++ GList *added_jobs; + + gint64 start_time; + gint64 last_update_time; +@@ -96,6 +103,9 @@ struct _ThunarTransferJob + + ThunarPreferences *preferences; + gboolean file_size_binary; ++ guint16 max_simultaneous_copies; ++ guint16 copy_from_same_device; ++ guint16 copy_to_same_device; + }; + + struct _ThunarTransferNode +@@ -109,6 +119,9 @@ struct _ThunarTransferNode + + G_DEFINE_TYPE (ThunarTransferJob, thunar_transfer_job, THUNAR_TYPE_JOB) + ++G_LOCK_DEFINE_STATIC(active_jobs); ++static GList *active_jobs = NULL; ++ + + + static void +@@ -137,6 +150,33 @@ thunar_transfer_job_class_init (ThunarTransferJobClass *klass) + NULL, + FALSE, + EXO_PARAM_READWRITE)); ++ /* ++ g_object_class_install_property (gobject_class, ++ PROP_MAX_SIMULTANEOUS_COPIES, ++ g_param_spec_uint ("max-simultaneous-copies", ++ "MaxSimultaneousCopies", ++ NULL, ++ 0, ++ 100, ++ 0, ++ EXO_PARAM_READWRITE)); ++ g_object_class_install_property (gobject_class, ++ PROP_COPY_FROM_SAME_DEVICE, ++ g_param_spec_enum ("copy-from-same-device", ++ "CopyFromSameDevice", ++ NULL, ++ THUNAR_TYPE_COPY_SAME_DEVICE, ++ THUNAR_COPY_SAME_DEVICE_SIMULTANEOUSLY, ++ EXO_PARAM_READWRITE)); ++ g_object_class_install_property (gobject_class, ++ PROP_COPY_TO_SAME_DEVICE, ++ g_param_spec_enum ("copy-to-same-device", ++ "CopyToSameDevice", ++ NULL, ++ THUNAR_TYPE_COPY_SAME_DEVICE, ++ THUNAR_COPY_SAME_DEVICE_SIMULTANEOUSLY, ++ EXO_PARAM_READWRITE)); ++ */ + } + + +@@ -147,10 +187,10 @@ thunar_transfer_job_init (ThunarTransferJob *job) + job->preferences = thunar_preferences_get (); + exo_binding_new (G_OBJECT (job->preferences), "misc-file-size-binary", + G_OBJECT (job), "file-size-binary"); +- + job->type = 0; + job->source_node_list = NULL; + job->target_file_list = NULL; ++ job->added_jobs = NULL; + job->total_size = 0; + job->total_progress = 0; + job->file_progress = 0; +@@ -163,16 +203,32 @@ thunar_transfer_job_init (ThunarTransferJob *job) + + + static void ++thunar_transfer_job_free (gpointer data) ++{ ++ ThunarTransferJob *job = data; ++ g_object_unref (job); ++} ++ ++ ++ ++static void + thunar_transfer_job_finalize (GObject *object) + { + ThunarTransferJob *job = THUNAR_TRANSFER_JOB (object); ++ GList *ljob; + + g_list_free_full (job->source_node_list, thunar_transfer_node_free); +- + thunar_g_file_list_free (job->target_file_list); +- + g_object_unref (job->preferences); +- ++ if (job->added_jobs != NULL) ++ g_list_free_full(job->added_jobs, thunar_transfer_job_free); ++ G_LOCK (active_jobs); ++ ljob = g_list_find (active_jobs, job); ++ if (G_LIKELY (ljob != NULL)) ++ { ++ active_jobs = g_list_remove_link (active_jobs, ljob); ++ } ++ G_UNLOCK (active_jobs); + (*G_OBJECT_CLASS (thunar_transfer_job_parent_class)->finalize) (object); + } + +@@ -846,26 +902,207 @@ thunar_transfer_job_verify_destination (ThunarTransferJob *transfer_job, + + + ++static GList * ++thunar_transfer_job_list (void) ++{ ++ GList *job_list; ++ G_LOCK (active_jobs); ++ job_list = g_list_copy(active_jobs); ++ G_UNLOCK (active_jobs); ++ return job_list; ++} ++ ++ ++ ++static gboolean ++thunar_transfer_job_matching_fs(ThunarTransferJob *newjob, ++ GFile *file1, ++ GFile *file2) ++{ ++ GFileInfo *info1; ++ GFileInfo *info2; ++ guint32 unix_device1; ++ guint32 unix_device2; ++ GError *err = NULL; ++ ++ info1 = g_file_query_info (file1, ++ G_FILE_ATTRIBUTE_UNIX_DEVICE, ++ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, ++ exo_job_get_cancellable (EXO_JOB (newjob)), ++ &err); ++ if (G_UNLIKELY (info1 == NULL || err != NULL)) ++ return FALSE; ++ unix_device1 = g_file_info_get_attribute_uint32(info1, G_FILE_ATTRIBUTE_UNIX_DEVICE); ++ err = NULL; ++ info2 = g_file_query_info (file2, ++ G_FILE_ATTRIBUTE_UNIX_DEVICE, ++ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, ++ exo_job_get_cancellable (EXO_JOB (newjob)), ++ &err); ++ if (G_UNLIKELY (info2 == NULL || err != NULL)) ++ return FALSE; ++ unix_device2 = g_file_info_get_attribute_uint32(info2, G_FILE_ATTRIBUTE_UNIX_DEVICE); ++ return (unix_device1 == unix_device2); ++} ++ ++ ++ ++static gboolean ++thunar_transfer_job_matching_source_fs(ThunarTransferJob *job, ++ ThunarTransferJob *newjob) ++{ ++ ThunarTransferNode *node; ++ GFile *file1; ++ GFile *file2; ++ ++ _thunar_return_val_if_fail (job != NULL, FALSE); ++ _thunar_return_val_if_fail (newjob != NULL, FALSE); ++ node = job->source_node_list->data; ++ file1 = node->source_file; ++ node = newjob->source_node_list->data; ++ file2 = node->source_file; ++ return thunar_transfer_job_matching_fs (newjob, file1, file2); ++} ++ ++ ++ ++static gboolean ++thunar_transfer_job_matching_target_fs(ThunarTransferJob *job, ++ ThunarTransferJob *newjob) ++{ ++ GFile *file1; ++ GFile *file2; ++ ++ _thunar_return_val_if_fail (job != NULL, FALSE); ++ _thunar_return_val_if_fail (newjob != NULL, FALSE); ++ file1 = job->target_file_list->data; ++ file2 = newjob->target_file_list->data; ++ return thunar_transfer_job_matching_fs (newjob, file1, file2); ++} ++ ++ ++ ++/** ++ * thunar_transfer_job_find_one_to_queue: ++ * @job : a #ThunarTransferJob. ++ * @max_simultaneous_copies : 0 = infinite, other = number of ++ * concurrent simultaneous copies allowed ++ * @copy_from_same_device : behavior when the source device is the ++ * same as another ++ * @copy_to_same_device : behavior when the target device is the ++ * same as another ++ * ++ * Tries to find a job to queue current file copy, ++ * rather than executing it on this job. ++ * ++ * Return value: the job to queue onto, or %NULL if none found matching ++ * the preferences. ++ **/ ++static ThunarTransferJob * ++thunar_transfer_job_find_one_to_queue (ThunarTransferJob *job, ++ guint max_simultaneous_copies, ++ ThunarCopySameDeviceMode copy_from_same_device_mode, ++ ThunarCopySameDeviceMode copy_to_same_device_mode) ++{ ++ ThunarTransferJob *queue_job = NULL; ++ GList *job_list; ++ GList *ljob; ++ ThunarTransferJob *inspected_job; ++ guint64 remaining_time_sec; ++ gboolean should_ask = FALSE; ++ ThunarJobResponse response; ++ ++ job_list = thunar_transfer_job_list(); ++ if (max_simultaneous_copies == 0 || g_list_length (job_list) < max_simultaneous_copies) ++ { ++ if (copy_from_same_device_mode == THUNAR_COPY_SAME_DEVICE_ASK || copy_to_same_device_mode == THUNAR_COPY_SAME_DEVICE_ASK) ++ { ++ for (ljob = job_list; ++ ljob != NULL; ++ ljob = ljob->next) ++ { ++ inspected_job = ljob->data; ++ remaining_time_sec = inspected_job->transfer_rate == 0 ? QUEUE_MIN_SEC + 1 : (inspected_job->total_size - inspected_job->total_progress) / inspected_job->transfer_rate; ++ if (inspected_job->total_size > QUEUE_MIN_SIZE && remaining_time_sec > QUEUE_MIN_SEC ++ && ( ++ (copy_from_same_device_mode == THUNAR_COPY_SAME_DEVICE_ASK && thunar_transfer_job_matching_source_fs (inspected_job, job)) ++ || (copy_to_same_device_mode == THUNAR_COPY_SAME_DEVICE_ASK && thunar_transfer_job_matching_target_fs (inspected_job, job)) ++ )) ++ { ++ should_ask = TRUE; ++ break; ++ } ++ } ++ } ++ if (should_ask) ++ { ++ // ask the user for simultaneous or queue ++ response = thunar_job_ask_queue_copy (THUNAR_JOB (job), ++ _("This copy share source or target device to another copy in progress.")); ++ if (response == THUNAR_JOB_RESPONSE_YES) ++ { ++ copy_from_same_device_mode = copy_to_same_device_mode = THUNAR_COPY_SAME_DEVICE_QUEUE; ++ } ++ else ++ { ++ copy_from_same_device_mode = copy_to_same_device_mode = THUNAR_COPY_SAME_DEVICE_SIMULTANEOUSLY; ++ } ++ g_list_free (job_list); ++ job_list = thunar_transfer_job_list(); ++ } ++ if (!should_ask || max_simultaneous_copies == 0 || g_list_length (job_list) < max_simultaneous_copies) ++ { ++ for (ljob = job_list; ++ ljob != NULL; ++ ljob = ljob->next) ++ { ++ inspected_job = ljob->data; ++ remaining_time_sec = inspected_job->transfer_rate == 0 ? QUEUE_MIN_SEC + 1 : (inspected_job->total_size - inspected_job->total_progress) / inspected_job->transfer_rate; ++ if (inspected_job->total_size > QUEUE_MIN_SIZE && remaining_time_sec > QUEUE_MIN_SEC) ++ { ++ if ((copy_from_same_device_mode == THUNAR_COPY_SAME_DEVICE_QUEUE && thunar_transfer_job_matching_source_fs (inspected_job, job)) ++ || (copy_to_same_device_mode == THUNAR_COPY_SAME_DEVICE_QUEUE && thunar_transfer_job_matching_target_fs (inspected_job, job))) ++ { ++ queue_job = inspected_job; ++ break; ++ } ++ } ++ } ++ } ++ } ++ g_list_free (job_list); ++ return queue_job; ++} ++ ++ ++ + static gboolean + thunar_transfer_job_execute (ExoJob *job, + GError **error) + { +- ThunarThumbnailCache *thumbnail_cache; +- ThunarTransferNode *node; +- ThunarApplication *application; +- ThunarJobResponse response; +- ThunarTransferJob *transfer_job = THUNAR_TRANSFER_JOB (job); +- GFileInfo *info; +- gboolean parent_exists; +- GError *err = NULL; +- GList *new_files_list = NULL; +- GList *snext; +- GList *sp; +- GList *tnext; +- GList *tp; +- GFile *target_parent; +- gchar *base_name; +- gchar *parent_display_name; ++ guint max_simultaneous_copies; ++ ThunarCopySameDeviceMode copy_from_same_device_mode; ++ ThunarCopySameDeviceMode copy_to_same_device_mode; ++ ThunarThumbnailCache *thumbnail_cache; ++ ThunarTransferNode *node; ++ ThunarApplication *application; ++ ThunarJobResponse response; ++ ThunarTransferJob *transfer_job = THUNAR_TRANSFER_JOB (job); ++ ThunarTransferJob *queue_job = NULL; ++ ThunarTransferJob *added_job = NULL; ++ GFileInfo *info; ++ gboolean parent_exists; ++ GError *err = NULL; ++ GList *new_files_list = NULL; ++ GList *snext; ++ GList *sp; ++ GList *sp_added; ++ GList *tnext; ++ GList *tp; ++ GList *tp_added; ++ GFile *target_parent; ++ gchar *base_name; ++ gchar *parent_display_name; + + _thunar_return_val_if_fail (THUNAR_IS_TRANSFER_JOB (job), FALSE); + _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -1050,16 +1287,52 @@ thunar_transfer_job_execute (ExoJob *job, + } + } + +- /* transfer starts now */ +- transfer_job->start_time = g_get_real_time (); +- +- /* perform the copy recursively for all source transfer nodes */ +- for (sp = transfer_job->source_node_list, tp = transfer_job->target_file_list; +- sp != NULL && tp != NULL && err == NULL; +- sp = sp->next, tp = tp->next) ++ g_object_get (G_OBJECT (transfer_job->preferences), "misc-max-simultaneous-copies", &max_simultaneous_copies, "misc-copy-from-same-device", ©_from_same_device_mode, "misc-copy-to-same-device", ©_to_same_device_mode, NULL); ++ queue_job = thunar_transfer_job_find_one_to_queue (transfer_job, max_simultaneous_copies, copy_from_same_device_mode, copy_to_same_device_mode); ++ if (queue_job == NULL) ++ { ++ G_LOCK (active_jobs); ++ active_jobs = g_list_prepend (active_jobs, transfer_job); ++ G_UNLOCK (active_jobs); ++ /* transfer starts now */ ++ transfer_job->start_time = g_get_real_time (); ++ /* perform the copy recursively for all source transfer nodes */ ++ for (sp = transfer_job->source_node_list, tp = transfer_job->target_file_list; ++ sp != NULL && tp != NULL && err == NULL; ++ sp = sp->next, tp = tp->next) ++ { ++ thunar_transfer_job_copy_node (transfer_job, sp->data, tp->data, NULL, ++ &new_files_list, &err); ++ } ++ while (transfer_job->added_jobs != NULL) ++ { ++ added_job = transfer_job->added_jobs->data; ++ transfer_job->added_jobs = g_list_remove_link(transfer_job->added_jobs, transfer_job->added_jobs); ++ if (G_LIKELY (err == NULL)) ++ { ++ for (sp_added = added_job->source_node_list, tp_added = added_job->target_file_list; ++ sp_added != NULL && tp_added != NULL && err == NULL; ++ sp_added = sp_added->next, tp_added = tp_added->next) ++ { ++ thunar_transfer_job_copy_node (transfer_job, sp_added->data, tp_added->data, NULL, ++ &new_files_list, &err); ++ } ++ } ++ g_object_unref (added_job); ++ } ++ } ++ else + { +- thunar_transfer_job_copy_node (transfer_job, sp->data, tp->data, NULL, +- &new_files_list, &err); ++ added_job = g_object_new (THUNAR_TYPE_TRANSFER_JOB, NULL); ++ added_job->type = transfer_job->type; ++ added_job->source_node_list = transfer_job->source_node_list; ++ added_job->target_file_list = transfer_job->target_file_list; ++ // transfer_job will be finalized/free and same for its resources ++ // fake it to have no resource ++ transfer_job->source_node_list = NULL; ++ transfer_job->target_file_list = NULL; ++ queue_job->added_jobs = g_list_append(queue_job->added_jobs, added_job); ++ queue_job->total_size += transfer_job->total_size; + } + } + +-- +2.8.2 diff --git a/xfce-base/thunar/metadata.xml b/xfce-base/thunar/metadata.xml new file mode 100644 index 0000000..d844c26 --- /dev/null +++ b/xfce-base/thunar/metadata.xml @@ -0,0 +1,12 @@ + + + + + xfce@gentoo.org + XFCE Team + + + Build the trash status indicator plugin for + the XFCE panel + + diff --git a/xfce-base/thunar/thunar-1.6.13_p1.ebuild b/xfce-base/thunar/thunar-1.6.13_p1.ebuild new file mode 100644 index 0000000..2b6cec3 --- /dev/null +++ b/xfce-base/thunar/thunar-1.6.13_p1.ebuild @@ -0,0 +1,83 @@ +# Copyright 1999-2017 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +EAPI=6 +inherit gnome2-utils virtualx xdg-utils + +MY_P=${P^} +MY_P=${MY_P%_p1} + +DESCRIPTION="File manager for the Xfce desktop environment and queued file transfer patch" +HOMEPAGE="https://www.xfce.org/projects/ https://docs.xfce.org/xfce/thunar/start" +SRC_URI="mirror://xfce/src/xfce/${PN}/${PV%.*}/${MY_P}.tar.bz2" + +LICENSE="GPL-2 LGPL-2" +SLOT="0" +KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~ia64 ~mips ~ppc ~ppc64 ~sparc ~x86 ~x86-fbsd ~amd64-linux ~x86-linux ~x86-solaris" +IUSE="+dbus exif libnotify pcre test +trash-panel-plugin udisks" + +GVFS_DEPEND=">=gnome-base/gvfs-1.18.3" +COMMON_DEPEND=">=dev-lang/perl-5.6 + >=dev-libs/glib-2.30:= + >=x11-libs/gdk-pixbuf-2.14:= + >=x11-libs/gtk+-2.24:2= + >=xfce-base/exo-0.10:= + >=xfce-base/libxfce4ui-4.10:= + >=xfce-base/libxfce4util-4.10.1:= + >=xfce-base/xfconf-4.10:= + dbus? ( >=dev-libs/dbus-glib-0.100:= ) + exif? ( >=media-libs/libexif-0.6.19:= ) + libnotify? ( >=x11-libs/libnotify-0.7:= ) + pcre? ( >=dev-libs/libpcre-6:= ) + trash-panel-plugin? ( >=xfce-base/xfce4-panel-4.10:= ) + udisks? ( virtual/libgudev:= )" +RDEPEND="${COMMON_DEPEND} + >=dev-util/desktop-file-utils-0.20-r1 + x11-misc/shared-mime-info + dbus? ( ${GVFS_DEPEND} ) + trash-panel-plugin? ( ${GVFS_DEPEND} ) + udisks? ( + virtual/udev + ${GVFS_DEPEND}[udisks,udev] + )" +DEPEND="${COMMON_DEPEND} + dev-util/intltool + sys-devel/gettext + virtual/pkgconfig" +REQUIRED_USE="trash-panel-plugin? ( dbus )" + +S=${WORKDIR}/${MY_P} + +DOCS=( AUTHORS ChangeLog FAQ HACKING NEWS README THANKS TODO ) + +PATCHES=( + "${FILESDIR}"/thunar-1.16.2-integer-overflow.patch + "${FILESDIR}"/thunar-queuedtransfer-20160702.patch +) + +src_configure() { + local myconf=( + $(use_enable dbus) + $(use_enable udisks gudev) + $(use_enable libnotify notifications) + $(use_enable exif) + $(use_enable pcre) + $(use_enable trash-panel-plugin tpa-plugin) + ) + + econf "${myconf[@]}" +} + +src_test() { + virtx emake check +} + +pkg_postinst() { + xdg_desktop_database_update + gnome2_icon_cache_update +} + +pkg_postrm() { + xdg_desktop_database_update + gnome2_icon_cache_update +} -- cgit v1.2.3-65-gdbad