diff options
author | Connor Behan | 2015-06-08 18:19:09 -0400 |
---|---|---|
committer | Connor Behan | 2015-06-08 18:19:09 -0400 |
commit | c2a5167e51ad6df995988005cb9baae6f2ec94d5 (patch) | |
tree | 080e5c971d7696362f356b121e99a9b967cdb674 | |
download | aur-c2a5167e51ad6df995988005cb9baae6f2ec94d5.tar.gz |
Initial import
-rw-r--r-- | .SRCINFO | 50 | ||||
-rw-r--r-- | PKGBUILD | 63 | ||||
-rw-r--r-- | notrash.patch | 161 | ||||
-rw-r--r-- | preview.patch | 451 | ||||
-rw-r--r-- | split_pane.patch | 327 | ||||
-rw-r--r-- | thunar.install | 14 | ||||
-rw-r--r-- | uca_num_files.patch | 411 |
7 files changed, 1477 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..33ed52c5cf9c --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,50 @@ +pkgbase = thunar-extended + pkgdesc = Thunar with split view, cursor audio preview and extra options for trash, desktop files and user actions + pkgver = 1.6.10 + pkgrel = 1 + url = http://thunar.xfce.org + install = thunar.install + arch = i686 + arch = x86_64 + groups = xfce4 + license = GPL2 + license = LGPL2.1 + makedepends = intltool + makedepends = pkgconfig + makedepends = xfce4-panel + makedepends = xfce4-dev-tools + depends = desktop-file-utils + depends = libexif + depends = hicolor-icon-theme + depends = libnotify + depends = udev + depends = gtk2 + depends = exo + depends = libxfce4util + depends = libxfce4ui + depends = libpng + depends = gstreamer0.10 + optdepends = gvfs: for trash support, mounting with udisk and remote filesystems + optdepends = gamin: for monitoring file changes without gvfs + optdepends = xfce4-panel: for trash applet + optdepends = tumbler: for thumbnail previews + optdepends = thunar-volman: manages removable devices + optdepends = thunar-archive-plugin: create and deflate archives + optdepends = thunar-media-tags-plugin: view/edit id3/ogg tags + provides = thunar=1.6.8 + conflicts = thunar + replaces = thunar + options = !libtool + source = http://archive.xfce.org/src/xfce/thunar/1.6/Thunar-1.6.10.tar.bz2 + source = notrash.patch + source = uca_num_files.patch + source = preview.patch + source = split_pane.patch + md5sums = 3089e1dca6e408641b07cd9c759dea5e + md5sums = d87f154a5fbd3709511ded0c9b9b0317 + md5sums = 69aa416e8694b8b608f767769b6dcd98 + md5sums = 6302de8c5061fbf769bc2b24e67256f9 + md5sums = ce443cf896934131427b7789da130097 + +pkgname = thunar-extended + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..178c97f92769 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,63 @@ +# Contributor: Connor Behan <connor.behan@gmail.com> + +pkgname=thunar-extended +pkgver=1.6.10 +pkgrel=1 +pkgdesc="Thunar with split view, cursor audio preview and extra options for trash, desktop files and user actions" +arch=(i686 x86_64) +license=('GPL2' 'LGPL2.1') +url="http://thunar.xfce.org" +groups=('xfce4') +conflicts=('thunar') +replaces=('thunar') +provides=('thunar=1.6.8') +depends=('desktop-file-utils' 'libexif' 'hicolor-icon-theme' 'libnotify' 'udev' \ + 'gtk2' 'exo' 'libxfce4util' 'libxfce4ui' 'libpng' 'gstreamer0.10') +makedepends=('intltool' 'pkgconfig' 'xfce4-panel' 'xfce4-dev-tools') +optdepends=('gvfs: for trash support, mounting with udisk and remote filesystems' + 'gamin: for monitoring file changes without gvfs' + 'xfce4-panel: for trash applet' + 'tumbler: for thumbnail previews' + 'thunar-volman: manages removable devices' + 'thunar-archive-plugin: create and deflate archives' + 'thunar-media-tags-plugin: view/edit id3/ogg tags') +options=('!libtool') +install=thunar.install +source=(http://archive.xfce.org/src/xfce/thunar/1.6/Thunar-${pkgver}.tar.bz2 + notrash.patch + uca_num_files.patch + preview.patch + split_pane.patch) + +build() { + cd "${srcdir}"/Thunar-${pkgver} + + # Xfce bugs 7352, 7353, 7354 and 10232 + patch -Np1 -i ../notrash.patch + patch -Np1 -i ../uca_num_files.patch + patch -Np1 -i ../preview.patch + patch -Np1 -i ../split_pane.patch + + mkdir m4 + sed -i -e 's/Thunar_CFLAGS/thunar_CFLAGS/' -e 's/Thunar_LDADD/thunar_LDADD/' thunar/Makefile.am + xdt-autogen + + ./configure --prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib \ + --localstatedir=/var --disable-static --disable-wallpaper-plugin \ + --enable-gstreamer --enable-gio-unix --enable-dbus --enable-exif \ + --enable-pcre --enable-gudev --disable-startup-notification \ + --enable-notifications + + make +} + +package() { + cd "${srcdir}"/Thunar-${pkgver} + make DESTDIR="${pkgdir}" install +} + +md5sums=('3089e1dca6e408641b07cd9c759dea5e' + 'd87f154a5fbd3709511ded0c9b9b0317' + '69aa416e8694b8b608f767769b6dcd98' + '6302de8c5061fbf769bc2b24e67256f9' + 'ce443cf896934131427b7789da130097') diff --git a/notrash.patch b/notrash.patch new file mode 100644 index 000000000000..7ce8a53ffef6 --- /dev/null +++ b/notrash.patch @@ -0,0 +1,161 @@ +diff -rudp Thunar-1.6.6.orig/thunar/thunar-application.c Thunar-1.6.6/thunar/thunar-application.c +--- Thunar-1.6.6.orig/thunar/thunar-application.c 2015-03-09 23:42:56.000000000 -0400 ++++ Thunar-1.6.6/thunar/thunar-application.c 2015-03-09 23:43:34.000000000 -0400 +@@ -1776,9 +1776,16 @@ thunar_application_unlink_files (ThunarA + gchar *message; + guint n_path_list = 0; + gint response; ++ gboolean isTrashEnabled; + + _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent)); + _thunar_return_if_fail (THUNAR_IS_APPLICATION (application)); ++ ++ g_object_get (G_OBJECT (application->preferences), "misc-enable-trash", &isTrashEnabled, NULL); ++ if (!isTrashEnabled) ++ { ++ permanently = TRUE; ++ } + + /* determine the paths for the files */ + for (lp = g_list_last (file_list); lp != NULL; lp = lp->prev, ++n_path_list) +@@ -1800,8 +1807,8 @@ thunar_application_unlink_files (ThunarA + if (G_UNLIKELY (permanently)) + { + /* parse the parent pointer */ +- screen = thunar_util_parse_parent (parent, &window); +- ++ screen = thunar_util_parse_parent (parent, &window); ++ + /* generate the question to confirm the delete operation */ + if (G_LIKELY (n_path_list == 1)) + { +diff -rudp Thunar-1.6.6.orig/thunar/thunar-preferences.c Thunar-1.6.6/thunar/thunar-preferences.c +--- Thunar-1.6.6.orig/thunar/thunar-preferences.c 2015-03-09 23:42:56.000000000 -0400 ++++ Thunar-1.6.6/thunar/thunar-preferences.c 2015-03-09 23:46:00.000000000 -0400 +@@ -75,6 +75,7 @@ enum + PROP_MISC_VOLUME_MANAGEMENT, + PROP_MISC_CASE_SENSITIVE, + PROP_MISC_DATE_STYLE, ++ PROP_MISC_ENABLE_TRASH, + PROP_EXEC_SHELL_SCRIPTS_BY_DEFAULT, + PROP_MISC_FOLDERS_FIRST, + PROP_MISC_FULL_PATH_IN_TITLE, +@@ -759,6 +760,18 @@ thunar_preferences_class_init (ThunarPre + THUNAR_ICON_SIZE_SMALLEST, + EXO_PARAM_READWRITE); + ++ /** ++ * ThunarPreferences:misc-enable-trash: ++ * ++ * If trash is disabled, files will be deleted permanently ++ **/ ++ preferences_props[PROP_MISC_ENABLE_TRASH] = ++ g_param_spec_boolean ("misc-enable-trash", ++ "misc-enable-trash", ++ NULL, ++ TRUE, ++ EXO_PARAM_READWRITE); ++ + /* install all properties */ + g_object_class_install_properties (gobject_class, N_PROPERTIES, preferences_props); + } +diff -rudp Thunar-1.6.6.orig/thunar/thunar-preferences-dialog.c Thunar-1.6.6/thunar/thunar-preferences-dialog.c +--- Thunar-1.6.6.orig/thunar/thunar-preferences-dialog.c 2015-03-09 23:42:56.000000000 -0400 ++++ Thunar-1.6.6/thunar/thunar-preferences-dialog.c 2015-03-09 23:43:34.000000000 -0400 +@@ -381,7 +381,7 @@ thunar_preferences_dialog_init (ThunarPr + gtk_frame_set_label_widget (GTK_FRAME (frame), label); + gtk_widget_show (label); + +- table = gtk_table_new (2, 2, FALSE); ++ 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); +@@ -599,7 +599,7 @@ thunar_preferences_dialog_init (ThunarPr + gtk_frame_set_label_widget (GTK_FRAME (frame), label); + gtk_widget_show (label); + +- table = gtk_table_new (2, 2, FALSE); ++ 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); +@@ -626,12 +626,18 @@ thunar_preferences_dialog_init (ThunarPr + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0); + gtk_widget_show (frame); + ++ button = gtk_check_button_new_with_mnemonic (_("Move items to Trash on _deletion.")); ++ exo_mutual_binding_new (G_OBJECT (dialog->preferences), "misc-enable-trash", G_OBJECT (button), "active"); ++ thunar_gtk_widget_set_tooltip (button, _( "By default, items are sent to the Trash on deletion. By disabling this option, items will be removed on deletion and will be lost forever. (DANGEROUS)" ) ); ++ gtk_table_attach (GTK_TABLE (table), button, 0,1,2,3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); ++ gtk_widget_show (button); ++ + 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); + gtk_widget_show (label); + +- table = gtk_table_new (2, 2, FALSE); ++ 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); +diff -rudp Thunar-1.6.6.orig/thunar/thunar-shortcuts-model.c Thunar-1.6.6/thunar/thunar-shortcuts-model.c +--- Thunar-1.6.6.orig/thunar/thunar-shortcuts-model.c 2015-03-09 23:42:56.000000000 -0400 ++++ Thunar-1.6.6/thunar/thunar-shortcuts-model.c 2015-03-09 23:43:34.000000000 -0400 +@@ -952,6 +952,8 @@ thunar_shortcuts_model_shortcut_places ( + GFile *desktop; + GFile *trash; + ThunarFile *file; ++ gboolean isTrashEnabled; ++ ThunarPreferences *preferences; + + /* add the places heading */ + shortcut = g_slice_new0 (ThunarShortcut); +@@ -992,9 +994,13 @@ thunar_shortcuts_model_shortcut_places ( + } + g_object_unref (desktop); + g_object_unref (home); ++ ++ preferences = thunar_preferences_get(); ++ g_object_get (G_OBJECT (preferences), "misc-enable-trash", &isTrashEnabled, NULL); ++ g_object_unref(preferences); + + /* append the trash icon if the trash is supported */ +- if (thunar_g_vfs_is_uri_scheme_supported ("trash")) ++ if (isTrashEnabled && thunar_g_vfs_is_uri_scheme_supported ("trash")) + { + trash = thunar_g_file_new_for_trash (); + file = thunar_file_get (trash, NULL); +diff -rudp Thunar-1.6.6.orig/thunar/thunar-tree-model.c Thunar-1.6.6/thunar/thunar-tree-model.c +--- Thunar-1.6.6.orig/thunar/thunar-tree-model.c 2015-03-09 23:42:56.000000000 -0400 ++++ Thunar-1.6.6/thunar/thunar-tree-model.c 2015-03-09 23:43:34.000000000 -0400 +@@ -286,12 +286,18 @@ thunar_tree_model_init (ThunarTreeModel + GList *devices; + GList *lp; + GNode *node; +- ++ ThunarPreferences *preferences; ++ gboolean isTrashEnabled; ++ + /* generate a unique stamp if we're in debug mode */ + #ifndef NDEBUG + model->stamp = g_random_int (); + #endif + ++ preferences = thunar_preferences_get(); ++ g_object_get (G_OBJECT (preferences), "misc-enable-trash", &isTrashEnabled, NULL); ++ g_object_unref(preferences); ++ + /* initialize the model data */ + model->sort_case_sensitive = TRUE; + model->visible_func = (ThunarTreeModelVisibleFunc) exo_noop_true; +@@ -324,7 +330,7 @@ thunar_tree_model_init (ThunarTreeModel + g_object_unref (desktop); + + /* append the trash icon if the trash is supported */ +- if (thunar_g_vfs_is_uri_scheme_supported ("trash")) ++ if (isTrashEnabled && thunar_g_vfs_is_uri_scheme_supported ("trash")) + system_paths = g_list_append (system_paths, thunar_g_file_new_for_trash ()); + + /* append the network icon if browsing the network is supported */ diff --git a/preview.patch b/preview.patch new file mode 100644 index 000000000000..5e90cd7667db --- /dev/null +++ b/preview.patch @@ -0,0 +1,451 @@ +diff -rudp Thunar-1.6.6.orig/configure.ac Thunar-1.6.6/configure.ac +--- Thunar-1.6.6.orig/configure.ac 2015-03-09 23:51:51.000000000 -0400 ++++ Thunar-1.6.6/configure.ac 2015-03-09 23:58:51.000000000 -0400 +@@ -181,6 +181,14 @@ XDT_CHECK_OPTIONAL_PACKAGE([LIBSTARTUP_N + [0.4], [startup-notification], + [startup notification library]) + ++dnl ************************************************* ++dnl *** Optional support for gstreamer *** ++dnl ************************************************* ++XDT_CHECK_OPTIONAL_PACKAGE([GSTREAMER], ++ [gstreamer-0.10], ++ [0.10], [gstreamer], ++ [nautilus-like mouseover preview]) ++ + dnl *************************************************************** + dnl *** Optional support for GUDev (required for thunar-volman) *** + dnl *************************************************************** +@@ -294,6 +302,11 @@ echo "* Startup Notification: + else + echo "* Startup Notification: no" + fi ++if test x"$GSTREAMER_FOUND" = x"yes"; then ++echo "* GStreamer: yes" ++else ++echo "* GStreamer: no" ++fi + if test x"$GUDEV_FOUND" = x"yes"; then + echo "* GUDev (required for thunar-volman): yes" + else +diff -rudp Thunar-1.6.6.orig/thunar/Makefile.am Thunar-1.6.6/thunar/Makefile.am +--- Thunar-1.6.6.orig/thunar/Makefile.am 2015-03-09 23:51:51.000000000 -0400 ++++ Thunar-1.6.6/thunar/Makefile.am 2015-03-09 23:58:51.000000000 -0400 +@@ -271,6 +271,14 @@ thunar_LDADD += \ + $(DBUS_LIBS) + endif + ++if HAVE_GSTREAMER ++Thunar_CFLAGS += \ ++ $(GSTREAMER_CFLAGS) ++ ++Thunar_LDADD += \ ++ $(GSTREAMER_LIBS) ++endif ++ + if HAVE_GIO_UNIX + thunar_CFLAGS += \ + $(GIO_UNIX_CFLAGS) +diff -rudp Thunar-1.6.6.orig/thunar/thunar-abstract-icon-view.c Thunar-1.6.6/thunar/thunar-abstract-icon-view.c +--- Thunar-1.6.6.orig/thunar/thunar-abstract-icon-view.c 2015-03-09 23:51:51.000000000 -0400 ++++ Thunar-1.6.6/thunar/thunar-abstract-icon-view.c 2015-03-10 00:04:16.000000000 -0400 +@@ -483,9 +483,16 @@ thunar_abstract_icon_view_button_press_e + ThunarPreferences *preferences; + gboolean in_tab; + const gchar *action_name; ++ ++ ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (abstract_icon_view); ++ GtkWidget *real_view = GTK_BIN (standard_view)->child; + + if (event->type == GDK_BUTTON_PRESS && event->button == 3) + { ++#ifdef HAVE_GSTREAMER ++ /* we don't want audio-preview to interfere when clicks are going on */ ++ g_signal_handlers_disconnect_by_func (real_view, thunar_standard_view_try_preview, standard_view); ++#endif + /* open the context menu on right clicks */ + if (exo_icon_view_get_item_at_pos (view, event->x, event->y, &path, NULL)) + { +@@ -511,12 +518,21 @@ thunar_abstract_icon_view_button_press_e + + /* open the context menu */ + thunar_standard_view_context_menu (THUNAR_STANDARD_VIEW (abstract_icon_view), event->button, event->time); +- } ++ ++#ifdef HAVE_GSTREAMER ++ /* turn audio-preview back on */ ++ g_signal_connect (G_OBJECT (real_view), "motion-notify-event", G_CALLBACK (thunar_standard_view_try_preview), standard_view); ++#endif ++ } + + return TRUE; + } + else if (event->type == GDK_BUTTON_PRESS && event->button == 2) + { ++#ifdef HAVE_GSTREAMER ++ /* again, this type of click should override audio-preview */ ++ g_signal_handlers_disconnect_by_func (real_view, thunar_standard_view_try_preview, standard_view); ++#endif + /* unselect all currently selected items */ + exo_icon_view_unselect_all (view); + +@@ -552,6 +568,11 @@ thunar_abstract_icon_view_button_press_e + + /* cleanup */ + gtk_tree_path_free (path); ++ ++#ifdef HAVE_GSTREAMER ++ /* we just clicked on a file so let the audio-preview work again */ ++ g_signal_connect (G_OBJECT (real_view), "motion-notify-event", G_CALLBACK (thunar_standard_view_try_preview), standard_view); ++#endif + } + else if (event->type == GDK_BUTTON_PRESS) + { +@@ -583,6 +604,9 @@ thunar_abstract_icon_view_button_release + ThunarAbstractIconView *abstract_icon_view) + { + GtkAction *action; ++ ++ ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (abstract_icon_view); ++ GtkWidget *real_view = GTK_BIN (standard_view)->child; + + _thunar_return_val_if_fail (EXO_IS_ICON_VIEW (view), FALSE); + _thunar_return_val_if_fail (THUNAR_IS_ABSTRACT_ICON_VIEW (abstract_icon_view), FALSE); +@@ -610,6 +634,11 @@ thunar_abstract_icon_view_button_release + /* redraw the abstract_icon view */ + gtk_widget_queue_draw (GTK_WIDGET (view)); + ++#ifdef HAVE_GSTREAMER ++ /* re-allow the audio-preview */ ++ g_signal_connect (G_OBJECT (real_view), "motion-notify-event", G_CALLBACK (thunar_standard_view_try_preview), standard_view); ++#endif ++ + return FALSE; + } + +diff -rudp Thunar-1.6.6.orig/thunar/thunar-standard-view.c Thunar-1.6.6/thunar/thunar-standard-view.c +--- Thunar-1.6.6.orig/thunar/thunar-standard-view.c 2015-03-09 23:51:51.000000000 -0400 ++++ Thunar-1.6.6/thunar/thunar-standard-view.c 2015-03-09 23:58:51.000000000 -0400 +@@ -31,6 +31,7 @@ + #endif + + #include <gdk/gdkkeysyms.h> ++#include <gdk/gdkcursor.h> + + #include <thunar/thunar-application.h> + #include <thunar/thunar-create-dialog.h> +@@ -59,7 +60,7 @@ + #endif + + +- ++#define MUSIC_NOTE { 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x80, 0x1f, 0x80, 0x39, 0x80, 0x21, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xfc, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x00, 0x7c, 0x00, 0x00, 0x00 }; + #define THUNAR_STANDARD_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNAR_TYPE_STANDARD_VIEW, ThunarStandardViewPrivate)) + + +@@ -280,6 +281,7 @@ static gboolean thunar_stand + static void thunar_standard_view_drag_scroll_timer_destroy (gpointer user_data); + static gboolean thunar_standard_view_drag_timer (gpointer user_data); + static void thunar_standard_view_drag_timer_destroy (gpointer user_data); ++static gboolean thunar_standard_view_preview_timer (GList *user_data); + static void thunar_standard_view_finished_thumbnailing (ThunarThumbnailer *thumbnailer, + guint request, + ThunarStandardView *standard_view); +@@ -768,6 +770,15 @@ thunar_standard_view_constructor (GType + /* stay informed about changes to the sort column/order */ + g_signal_connect (G_OBJECT (standard_view->model), "sort-column-changed", G_CALLBACK (thunar_standard_view_sort_column_changed), standard_view); + ++#ifdef HAVE_GSTREAMER ++ /* stay informed about what audio-preview might need to happen */ ++ g_signal_connect (G_OBJECT (view), "motion-notify-event", G_CALLBACK (thunar_standard_view_try_preview), standard_view); ++ ++ /* initialize the player */ ++ gst_init (NULL, NULL); ++ standard_view->play = gst_element_factory_make ("playbin", "play"); ++#endif ++ + /* setup support to navigate using a horizontal mouse wheel and the back and forward buttons */ + g_signal_connect (G_OBJECT (view), "scroll-event", G_CALLBACK (thunar_standard_view_scroll_event), object); + g_signal_connect (G_OBJECT (view), "button-press-event", G_CALLBACK (thunar_standard_view_button_press_event), object); +@@ -908,6 +919,12 @@ thunar_standard_view_finalize (GObject * + + /* release the scroll_to_files hash table */ + g_hash_table_destroy (standard_view->priv->scroll_to_files); ++ ++#ifdef HAVE_GSTREAMER ++ /* stop audio-preview and release the gstreamer reference */ ++ gst_element_set_state (standard_view->play, GST_STATE_NULL); ++ gst_object_unref (GST_OBJECT (standard_view->play)); ++#endif + + (*G_OBJECT_CLASS (thunar_standard_view_parent_class)->finalize) (object); + } +@@ -3007,6 +3024,214 @@ thunar_standard_view_motion_notify_event + + + ++#ifdef HAVE_GSTREAMER ++ ++/** ++ * thunar_standard_view_try_preview: ++ * @real_view : a GtkIconView or GtkTreeView. ++ * @event : another motion_notify_event for the times when no mouse button is held down. ++ * @standard_view : a #ThunarStandardView instance. ++ * ++ * An alternative motion_notify_event signal handler that checks whether any audio files are under the cursor ++ * and plays them in a short amount of time if the cursor stays there. ++ **/ ++gboolean ++thunar_standard_view_try_preview (GtkWidget *real_view, ++ GdkEventMotion *event, ++ ThunarStandardView *standard_view) ++{ ++ ThunarPreferences *preferences; ++ gchar *view_type; ++ gboolean item_found; ++ gboolean wrong_mime = TRUE; ++ ++ GtkTreePath *path = NULL; ++ GtkTreeIter iter; ++ ++ ThunarFile *file; ++ gchar *mime_type; ++ GList *preview_timer_list = NULL; ++ ++ preferences = thunar_preferences_get(); ++ g_object_get(G_OBJECT(preferences), "last-view", &view_type, NULL); ++ g_object_unref(preferences); ++ ++ if (strncmp(view_type, "ThunarDetailsView", 17) == 0) ++ { ++ item_found = gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW(real_view), event->x, event->y, &path, NULL, NULL, NULL); ++ } ++ else ++ { ++ item_found = exo_icon_view_get_item_at_pos (EXO_ICON_VIEW (real_view), event->x, event->y, &path, NULL); ++ } ++ ++ g_free(view_type); ++ ++ if (G_LIKELY (item_found)) ++ { ++ gtk_tree_model_get_iter (GTK_TREE_MODEL (standard_view->model), &iter, path); ++ file = thunar_list_model_get_file (standard_view->model, &iter); ++ ++ if (G_LIKELY (file != NULL)) ++ { ++ mime_type = thunar_file_get_content_type (file); ++ if (G_LIKELY (mime_type != NULL)) ++ { ++ wrong_mime = strncmp(mime_type, "audio/", 6); ++ } ++ } ++ ++ if (G_UNLIKELY (!wrong_mime)) ++ { ++ if (G_LIKELY (path != NULL)) ++ { ++ preview_timer_list = g_list_append(preview_timer_list, standard_view); ++ preview_timer_list = g_list_append(preview_timer_list, g_file_get_uri(thunar_file_get_file(file))); ++ ++ gtk_tree_path_free(path); ++ g_timeout_add (50, (GtkFunction)thunar_standard_view_preview_timer, preview_timer_list); ++ g_signal_handlers_disconnect_by_func (real_view, thunar_standard_view_try_preview, standard_view); ++ ++ return FALSE; ++ } ++ } ++ else ++ { ++ g_object_unref (G_OBJECT (file)); ++ } ++ } ++ ++ if (standard_view->playing) ++ { ++ gdk_window_set_cursor (GTK_WIDGET (standard_view)->window, NULL); ++ gst_element_set_state (standard_view->play, GST_STATE_NULL); ++ standard_view->playing = FALSE; ++ } ++ return FALSE; ++} ++ ++ ++ ++static gboolean ++thunar_standard_view_preview_timer (GList *user_data) ++{ ++ ThunarStandardView *standard_view = user_data->data; ++ gchar *absolute_path = user_data->next->data; ++ ++ GtkWidget *real_view = GTK_BIN (standard_view)->child; ++ ThunarPreferences *preferences; ++ gchar *view_type; ++ gboolean item_found; ++ ++ GdkCursor *cursor; ++ GdkPixmap *bitmap; ++ GdkColor fg = { 0, 0, 0, 0 }; ++ GdkColor bg = { 0, 65535, 65535, 65535 }; ++ static unsigned char music_note_bits[] = MUSIC_NOTE; ++ ++ GtkTreePath *new_path = NULL; ++ GtkTreeIter iter; ++ ThunarFile *file; ++ gint x, y; ++ gint wx, wy; ++ gint bx, by; ++ ++ static int call_number = 0; ++ ++ g_signal_handlers_disconnect_by_func (real_view, thunar_standard_view_try_preview, standard_view); ++ gtk_widget_get_pointer (GTK_WIDGET (standard_view), &wx, &wy); ++ ++ preferences = thunar_preferences_get(); ++ g_object_get(G_OBJECT(preferences), "last-view", &view_type, NULL); ++ g_object_unref(preferences); ++ ++ if (strncmp(view_type, "ThunarDetailsView", 17) == 0) ++ { ++ gtk_tree_view_convert_widget_to_bin_window_coords (GTK_TREE_VIEW(real_view), wx, wy, &bx, &by); ++ item_found = gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW(real_view), bx, by, &new_path, NULL, NULL, NULL); ++ } ++ else ++ { ++ exo_icon_view_widget_to_icon_coords(EXO_ICON_VIEW (real_view), wx, wy, &x, &y); ++ item_found = exo_icon_view_get_item_at_pos (EXO_ICON_VIEW (real_view), x, y, &new_path, NULL); ++ } ++ ++ g_free(view_type); ++ ++ if (standard_view->playing) ++ { ++ if (!item_found) ++ { ++ gdk_window_set_cursor (GTK_WIDGET (standard_view)->window, NULL); ++ gst_element_set_state (standard_view->play, GST_STATE_NULL); ++ standard_view->playing = FALSE; ++ } ++ else ++ { ++ gtk_tree_model_get_iter (GTK_TREE_MODEL (standard_view->model), &iter, new_path); ++ file = thunar_list_model_get_file (standard_view->model, &iter); ++ ++ if (strcmp(g_file_get_uri(thunar_file_get_file(file)), absolute_path)) ++ { ++ gdk_window_set_cursor (GTK_WIDGET (standard_view)->window, NULL); ++ gst_element_set_state (standard_view->play, GST_STATE_NULL); ++ standard_view->playing = FALSE; ++ } ++ } ++ } ++ else ++ { ++ if (item_found) ++ { ++ gtk_tree_model_get_iter (GTK_TREE_MODEL (standard_view->model), &iter, new_path); ++ file = thunar_list_model_get_file (standard_view->model, &iter); ++ ++ if (!strcmp(g_file_get_uri(thunar_file_get_file(file)), absolute_path)) ++ { ++ call_number++; ++ ++ if (call_number == 1) ++ { ++ bitmap = gdk_bitmap_create_from_data (NULL, music_note_bits, 16, 16); ++ cursor = gdk_cursor_new_from_pixmap (bitmap, bitmap, &fg, &bg, 8, 8); ++ gdk_window_set_cursor (GTK_WIDGET (standard_view)->window, cursor); ++ ++ g_object_set (G_OBJECT (standard_view->play), "uri", g_file_get_uri(thunar_file_get_file(file)), NULL); ++ } ++ ++ if (call_number > 40) ++ { ++ gst_element_set_state (standard_view->play, GST_STATE_PLAYING); ++ standard_view->playing = TRUE; ++ ++ call_number = 0; ++ gtk_tree_path_free (new_path); ++ g_signal_connect (G_OBJECT (real_view), "motion-notify-event", G_CALLBACK (thunar_standard_view_try_preview), standard_view); ++ return FALSE; ++ } ++ return TRUE; ++ } ++ else ++ { ++ gdk_window_set_cursor (GTK_WIDGET (standard_view)->window, NULL); ++ } ++ } ++ else ++ { ++ gdk_window_set_cursor (GTK_WIDGET (standard_view)->window, NULL); ++ } ++ } ++ ++ call_number = 0; ++ gtk_tree_path_free (new_path); ++ g_signal_connect (G_OBJECT (real_view), "motion-notify-event", G_CALLBACK (thunar_standard_view_try_preview), standard_view); ++ return FALSE; ++} ++ ++#endif ++ ++ ++ + static gboolean + thunar_standard_view_scroll_event (GtkWidget *view, + GdkEventScroll *event, +@@ -3851,7 +4076,15 @@ thunar_standard_view_drag_scroll_timer ( + static void + thunar_standard_view_drag_scroll_timer_destroy (gpointer user_data) + { +- THUNAR_STANDARD_VIEW (user_data)->priv->drag_scroll_timer_id = 0; ++ ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (user_data); ++ GtkWidget *view = GTK_BIN (standard_view)->child; ++ ++ standard_view->priv->drag_scroll_timer_id = 0; ++ ++#ifdef HAVE_GSTREAMER ++ /* enables audio-preview again */ ++ g_signal_connect (G_OBJECT (view), "motion-notify-event", G_CALLBACK (thunar_standard_view_try_preview), standard_view); ++#endif + } + + +diff -rudp Thunar-1.6.6.orig/thunar/thunar-standard-view.h Thunar-1.6.6/thunar/thunar-standard-view.h +--- Thunar-1.6.6.orig/thunar/thunar-standard-view.h 2015-03-09 23:51:51.000000000 -0400 ++++ Thunar-1.6.6/thunar/thunar-standard-view.h 2015-03-09 23:58:51.000000000 -0400 +@@ -26,6 +26,10 @@ + #include <thunar/thunar-preferences.h> + #include <thunar/thunar-view.h> + ++#ifdef HAVE_GSTREAMER ++#include <gst/gst.h> ++#endif ++ + G_BEGIN_DECLS; + + typedef struct _ThunarStandardViewPrivate ThunarStandardViewPrivate; +@@ -138,6 +142,11 @@ struct _ThunarStandardView + ExoBinding *loading_binding; + gboolean loading; + ++#ifdef HAVE_GSTREAMER ++ gboolean playing; ++ GstElement *play; ++#endif ++ + ThunarStandardViewPrivate *priv; + }; + +@@ -152,6 +161,10 @@ void thunar_standard_view_queue_popup + + void thunar_standard_view_selection_changed (ThunarStandardView *standard_view); + ++gboolean thunar_standard_view_try_preview (GtkWidget *real_view, ++ GdkEventMotion *event, ++ ThunarStandardView *standard_view); ++ + G_END_DECLS; + + #endif /* !__THUNAR_STANDARD_VIEW_H__ */ diff --git a/split_pane.patch b/split_pane.patch new file mode 100644 index 000000000000..5a290a60ab77 --- /dev/null +++ b/split_pane.patch @@ -0,0 +1,327 @@ +diff -rupN Thunar-1.6.7/thunar/thunar-standard-view.c Thunar-1.6.7-splitview/thunar/thunar-standard-view.c +--- Thunar-1.6.7/thunar/thunar-standard-view.c 2015-04-18 16:25:18.000000000 +0200 ++++ Thunar-1.6.7-splitview/thunar/thunar-standard-view.c 2015-04-24 02:08:46.234849486 +0200 +@@ -4262,8 +4262,8 @@ thunar_standard_view_queue_popup (Thunar + standard_view, thunar_standard_view_drag_timer_destroy); + + /* register the motion notify and the button release events on the real view */ +- g_signal_connect (G_OBJECT (view), "button-release-event", G_CALLBACK (thunar_standard_view_button_release_event), standard_view); +- g_signal_connect (G_OBJECT (view), "motion-notify-event", G_CALLBACK (thunar_standard_view_motion_notify_event), standard_view); ++ g_signal_connect_after (G_OBJECT (view), "button-release-event", G_CALLBACK (thunar_standard_view_button_release_event), standard_view); ++ g_signal_connect_after (G_OBJECT (view), "motion-notify-event", G_CALLBACK (thunar_standard_view_motion_notify_event), standard_view); + } + } + +diff -rupN Thunar-1.6.7/thunar/thunar-window.c Thunar-1.6.7-splitview/thunar/thunar-window.c +--- Thunar-1.6.7/thunar/thunar-window.c 2015-04-18 16:25:18.000000000 +0200 ++++ Thunar-1.6.7-splitview/thunar/thunar-window.c 2015-04-24 02:28:18.421547235 +0200 +@@ -81,6 +81,7 @@ enum + enum + { + BACK, ++ PANE_WINDOW, + RELOAD, + TOGGLE_SIDEPANE, + TOGGLE_MENUBAR, +@@ -104,6 +105,7 @@ static void thunar_window_set_proper + const GValue *value, + GParamSpec *pspec); + static gboolean thunar_window_back (ThunarWindow *window); ++static gboolean thunar_window_pane_window (ThunarWindow *window); + static gboolean thunar_window_reload (ThunarWindow *window, + gboolean reload_info); + static gboolean thunar_window_toggle_sidepane (ThunarWindow *window); +@@ -249,6 +251,9 @@ static gboolean thunar_window_save_geome + static void thunar_window_save_geometry_timer_destroy (gpointer user_data); + static void thunar_window_set_zoom_level (ThunarWindow *window, + ThunarZoomLevel zoom_level); ++static gboolean thunar_window_notebook_select (GtkWidget *notebook, ++ GdkEvent *event, ++ ThunarWindow *window); + + + +@@ -258,6 +263,7 @@ struct _ThunarWindowClass + + /* internal action signals */ + gboolean (*back) (ThunarWindow *window); ++ gboolean (*pane_window) (ThunarWindow *window); + gboolean (*reload) (ThunarWindow *window, + gboolean reload_info); + gboolean (*toggle_sidepane) (ThunarWindow *window); +@@ -311,9 +317,12 @@ struct _ThunarWindow + GtkWidget *menubar; + GtkWidget *spinner; + GtkWidget *paned; ++ GtkWidget *panes; + GtkWidget *sidepane; + GtkWidget *view_box; + GtkWidget *notebook; ++ GtkWidget *notebook1; ++ GtkWidget *notebook2; + GtkWidget *view; + GtkWidget *statusbar; + +@@ -420,6 +429,7 @@ thunar_window_class_init (ThunarWindowCl + gtkwidget_class->configure_event = thunar_window_configure_event; + + klass->back = thunar_window_back; ++ klass->pane_window = thunar_window_pane_window; + klass->reload = thunar_window_reload; + klass->toggle_sidepane = thunar_window_toggle_sidepane; + klass->toggle_menubar = thunar_window_toggle_menubar; +@@ -503,6 +513,23 @@ thunar_window_class_init (ThunarWindowCl + G_TYPE_BOOLEAN, 0); + + /** ++ * ThunarWindow::pane-window: ++ * @window : a #ThunarWindow instance. ++ * ++ * Emitted whenever the user requests to pane the window ++ * of the currently displayed folder. This is an internal ++ * signal used to bind the action to keys. ++ **/ ++ window_signals[PANE_WINDOW] = ++ g_signal_new (I_("pane-window"), ++ G_TYPE_FROM_CLASS (klass), ++ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, ++ G_STRUCT_OFFSET (ThunarWindowClass, pane_window), ++ g_signal_accumulator_true_handled, NULL, ++ _thunar_marshal_BOOLEAN__VOID, ++ G_TYPE_BOOLEAN, 0); ++ ++ /** + * ThunarWindow::reload: + * @window : a #ThunarWindow instance. + * +@@ -623,6 +650,7 @@ thunar_window_class_init (ThunarWindowCl + /* setup the key bindings for the windows */ + binding_set = gtk_binding_set_by_class (klass); + gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, 0, "back", 0); ++ gtk_binding_entry_add_signal (binding_set, GDK_F3, 0, "pane-window", 0); + gtk_binding_entry_add_signal (binding_set, GDK_F5, 0, "reload", 1, G_TYPE_BOOLEAN, TRUE); + gtk_binding_entry_add_signal (binding_set, GDK_F9, 0, "toggle-sidepane", 0); + gtk_binding_entry_add_signal (binding_set, GDK_F10, 0, "toggle-menubar", 0); +@@ -861,31 +889,44 @@ thunar_window_init (ThunarWindow *window + g_signal_connect_swapped (window->paned, "button-release-event", G_CALLBACK (thunar_window_save_paned), window); + + window->view_box = gtk_table_new (3, 1, FALSE); +- gtk_paned_pack2 (GTK_PANED (window->paned), window->view_box, TRUE, FALSE); ++ gtk_paned_add2 (GTK_PANED (window->paned), window->view_box); + gtk_widget_show (window->view_box); + ++ /* Create panes when the notebook will be */ ++ window->panes = gtk_hpaned_new (); ++ gtk_widget_add_events (window->panes, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK); ++ gtk_table_attach (GTK_TABLE (window->view_box), window->panes, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); ++ gtk_widget_show (window->panes); ++ + /* tabs */ +- window->notebook = gtk_notebook_new (); +- gtk_table_attach (GTK_TABLE (window->view_box), window->notebook, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); +- g_signal_connect (G_OBJECT (window->notebook), "switch-page", G_CALLBACK (thunar_window_notebook_switch_page), window); +- g_signal_connect (G_OBJECT (window->notebook), "page-added", G_CALLBACK (thunar_window_notebook_page_added), window); +- g_signal_connect (G_OBJECT (window->notebook), "page-removed", G_CALLBACK (thunar_window_notebook_page_removed), window); +- g_signal_connect_after (G_OBJECT (window->notebook), "button-press-event", G_CALLBACK (thunar_window_notebook_button_press_event), window); +- g_signal_connect (G_OBJECT (window->notebook), "popup-menu", G_CALLBACK (thunar_window_notebook_popup_menu), window); +- g_signal_connect (G_OBJECT (window->notebook), "create-window", G_CALLBACK (thunar_window_notebook_create_window), window); +- gtk_notebook_set_show_border (GTK_NOTEBOOK (window->notebook), FALSE); +- gtk_notebook_set_homogeneous_tabs (GTK_NOTEBOOK (window->notebook), TRUE); +- gtk_notebook_set_scrollable (GTK_NOTEBOOK (window->notebook), TRUE); +- gtk_container_set_border_width (GTK_CONTAINER (window->notebook), 0); +- gtk_notebook_set_group_name (GTK_NOTEBOOK (window->notebook), "thunar-tabs"); +- gtk_widget_show (window->notebook); ++ // notebook1 ++ window->notebook1 = gtk_notebook_new (); ++ gtk_paned_pack1 (GTK_PANED (window->panes), window->notebook1, TRUE, FALSE); ++ g_signal_connect (G_OBJECT (window->notebook1), "switch-page", G_CALLBACK (thunar_window_notebook_switch_page), window); ++ g_signal_connect (G_OBJECT (window->notebook1), "page-added", G_CALLBACK (thunar_window_notebook_page_added), window); ++ g_signal_connect (G_OBJECT (window->notebook1), "page-removed", G_CALLBACK (thunar_window_notebook_page_removed), window); ++ g_signal_connect_after (G_OBJECT (window->notebook1), "button-press-event", G_CALLBACK (thunar_window_notebook_button_press_event), window); ++ g_signal_connect (G_OBJECT (window->notebook1), "popup-menu", G_CALLBACK (thunar_window_notebook_popup_menu), window); ++ g_signal_connect (G_OBJECT (window->notebook1), "create-window", G_CALLBACK (thunar_window_notebook_create_window), window); ++ gtk_notebook_set_show_border (GTK_NOTEBOOK (window->notebook1), FALSE); ++ gtk_notebook_set_homogeneous_tabs (GTK_NOTEBOOK (window->notebook1), TRUE); ++ gtk_notebook_set_scrollable (GTK_NOTEBOOK (window->notebook1), TRUE); ++ gtk_container_set_border_width (GTK_CONTAINER (window->notebook1), 0); ++ gtk_notebook_set_group_name (GTK_NOTEBOOK (window->notebook1), "thunar-tabs"); ++ gtk_widget_show (window->notebook1); + + /* drop the notebook borders */ + style = gtk_rc_style_new (); + style->xthickness = style->ythickness = 0; +- gtk_widget_modify_style (window->notebook, style); ++ gtk_widget_modify_style (window->notebook1, style); + g_object_unref (G_OBJECT (style)); + ++ // notebook2 ++ window->notebook2 = NULL; ++ ++ /* The notebook selected and actived */ ++ window->notebook = window->notebook1; ++ + /* determine the selected location selector */ + if (exo_str_is_equal (last_location_bar, g_type_name (THUNAR_TYPE_LOCATION_BUTTONS))) + type = THUNAR_TYPE_LOCATION_BUTTONS; +@@ -1392,6 +1433,130 @@ thunar_window_binding_create (ThunarWind + + + ++static gboolean ++thunar_window_pane_window (ThunarWindow *window) ++{ ++ ThunarFile *directory; ++ GtkRcStyle *style; ++ ++ _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); ++ _thunar_return_val_if_fail (window->view_type != G_TYPE_NONE, FALSE); ++ ++ /* if two panes are showed then remove not selected one */ ++ if (window->notebook1 != NULL && window->notebook2 != NULL) ++ { ++ /* notebook1 is the selected notebook so it destroys notebook2 */ ++ if (window->notebook == window->notebook1) ++ { ++ gtk_widget_destroy (window->notebook2); ++ window->notebook2 = NULL; ++ } ++ /* notebook2 is the selected notebook so it destroys notebook1 */ ++ else ++ { ++ gtk_widget_destroy (window->notebook1); ++ window->notebook1 = NULL; ++ } ++ } ++ /* notebook1 is null so it crates it */ ++ else if (window->notebook1 == NULL) ++ { ++ /* create the notebook1 */ ++ window->notebook1 = gtk_notebook_new (); ++ gtk_paned_pack1 (GTK_PANED (window->panes), window->notebook1, TRUE, FALSE); ++ g_signal_connect (G_OBJECT (window->notebook1), "switch-page", G_CALLBACK (thunar_window_notebook_switch_page), window); ++ g_signal_connect (G_OBJECT (window->notebook1), "page-added", G_CALLBACK (thunar_window_notebook_page_added), window); ++ g_signal_connect (G_OBJECT (window->notebook1), "page-removed", G_CALLBACK (thunar_window_notebook_page_removed), window); ++ g_signal_connect_after (G_OBJECT (window->notebook1), "button-press-event", G_CALLBACK (thunar_window_notebook_button_press_event), window); ++ g_signal_connect (G_OBJECT (window->notebook1), "popup-menu", G_CALLBACK (thunar_window_notebook_popup_menu), window); ++ g_signal_connect (G_OBJECT (window->notebook1), "create-window", G_CALLBACK (thunar_window_notebook_create_window), window); ++ gtk_notebook_set_show_border (GTK_NOTEBOOK (window->notebook1), FALSE); ++ gtk_notebook_set_homogeneous_tabs (GTK_NOTEBOOK (window->notebook1), TRUE); ++ gtk_notebook_set_scrollable (GTK_NOTEBOOK (window->notebook1), TRUE); ++ gtk_container_set_border_width (GTK_CONTAINER (window->notebook1), 0); ++ gtk_notebook_set_group_name (GTK_NOTEBOOK (window->notebook1), "thunar-tabs"); ++ gtk_widget_show (window->notebook1); ++ ++ /* drop the notebook borders */ ++ style = gtk_rc_style_new (); ++ style->xthickness = style->ythickness = 0; ++ gtk_widget_modify_style (window->notebook1, style); ++ g_object_unref (G_OBJECT (style)); ++ ++ /* set notebook2 to selected notebook */ ++ window->notebook = window->notebook1; ++ directory = thunar_window_get_current_directory (window); ++ thunar_window_notebook_insert (window, directory); ++ } ++ /* Otherwise notebook2 is null so it creates it */ ++ else ++ { ++ /* create the notebook2 */ ++ window->notebook2 = gtk_notebook_new (); ++ gtk_paned_pack2 (GTK_PANED (window->panes), window->notebook2, TRUE, FALSE); ++ g_signal_connect (G_OBJECT (window->notebook2), "switch-page", G_CALLBACK (thunar_window_notebook_switch_page), window); ++ g_signal_connect (G_OBJECT (window->notebook2), "page-added", G_CALLBACK (thunar_window_notebook_page_added), window); ++ g_signal_connect (G_OBJECT (window->notebook2), "page-removed", G_CALLBACK (thunar_window_notebook_page_removed), window); ++ g_signal_connect_after (G_OBJECT (window->notebook2), "button-press-event", G_CALLBACK (thunar_window_notebook_button_press_event), window); ++ g_signal_connect (G_OBJECT (window->notebook2), "popup-menu", G_CALLBACK (thunar_window_notebook_popup_menu), window); ++ g_signal_connect (G_OBJECT (window->notebook2), "create-window", G_CALLBACK (thunar_window_notebook_create_window), window); ++ gtk_notebook_set_show_border (GTK_NOTEBOOK (window->notebook2), FALSE); ++ gtk_notebook_set_homogeneous_tabs (GTK_NOTEBOOK (window->notebook2), TRUE); ++ gtk_notebook_set_scrollable (GTK_NOTEBOOK (window->notebook2), TRUE); ++ gtk_container_set_border_width (GTK_CONTAINER (window->notebook2), 0); ++ gtk_notebook_set_group_name (GTK_NOTEBOOK (window->notebook2), "thunar-tabs"); ++ gtk_widget_show (window->notebook2); ++ ++ /* drop the notebook borders */ ++ style = gtk_rc_style_new (); ++ style->xthickness = style->ythickness = 0; ++ gtk_widget_modify_style (window->notebook2, style); ++ g_object_unref (G_OBJECT (style)); ++ ++ /* set notebook2 to selected notebook */ ++ window->notebook = window->notebook2; ++ directory = thunar_window_get_current_directory (window); ++ thunar_window_notebook_insert (window, directory); ++ } ++ ++ return TRUE; ++} ++ ++ ++ ++static gboolean ++thunar_window_notebook_select (GtkWidget *view, ++ GdkEvent *event, ++ ThunarWindow *window) ++{ ++ GtkWidget *selected_notebook; ++ gint current_page_n; ++ GtkWidget *current_page; ++ ++ /* if there is not two panes (notebook2 == NULL) nothing to do */ ++ if (window->notebook2 == NULL) ++ return FALSE; ++ ++ /* notebook selected */ ++ selected_notebook = gtk_widget_get_ancestor (view, GTK_TYPE_NOTEBOOK); ++ ++ /* if the notebook selected is the same than the current notebook selected nothing to do */ ++ if (selected_notebook == window->notebook) ++ return FALSE; ++ ++ /* select and activate selected notebook */ ++ window->notebook = selected_notebook; ++ current_page_n = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook)); ++ current_page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), current_page_n); ++ thunar_component_set_ui_manager (THUNAR_COMPONENT (window->view), NULL); ++ window->view = NULL; ++ thunar_window_notebook_switch_page (window->notebook, current_page, current_page_n, window); ++ ++ return FALSE; ++} ++ ++ ++ + static void + thunar_window_notebook_switch_page (GtkWidget *notebook, + GtkWidget *page, +@@ -1405,7 +1570,8 @@ thunar_window_notebook_switch_page (GtkW + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + _thunar_return_if_fail (THUNAR_IS_VIEW (page)); +- _thunar_return_if_fail (window->notebook == notebook); ++ _thunar_return_if_fail (window->notebook1 == notebook || ++ window->notebook2 == notebook); + + /* leave if nothing changed */ + if (window->view == page) +@@ -1553,7 +1719,7 @@ thunar_window_notebook_page_removed (Gtk + thunar_component_set_ui_manager (THUNAR_COMPONENT (page), NULL); + + n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)); +- if (n_pages == 0) ++ if (n_pages == 0 && window->notebook2 == NULL) + { + /* destroy the window */ + gtk_widget_destroy (GTK_WIDGET (window)); +@@ -1784,6 +1950,11 @@ thunar_window_notebook_insert (ThunarWin + gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (window->notebook), view, TRUE); + gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (window->notebook), view, TRUE); + ++ /* connect signal view */ ++ gtk_widget_add_events (GTK_WIDGET (view), GDK_BUTTON_PRESS_MASK); ++ g_signal_connect (G_OBJECT (GTK_BIN (view)->child), "button-press-event", G_CALLBACK (thunar_window_notebook_select), window); ++ g_signal_connect (G_OBJECT (GTK_BIN (view)->child), "button-release-event", G_CALLBACK (thunar_window_notebook_select), window); ++ + /* take focus on the view */ + gtk_widget_grab_focus (view); + } diff --git a/thunar.install b/thunar.install new file mode 100644 index 000000000000..28fdb48fb3ca --- /dev/null +++ b/thunar.install @@ -0,0 +1,14 @@ +post_install() { + update-desktop-database -q + gtk-update-icon-cache -q -t -f usr/share/icons/hicolor +} + +post_upgrade() { + post_install $1 +} + +post_remove() { + update-desktop-database -q + gtk-update-icon-cache -q -t -f usr/share/icons/hicolor +} + diff --git a/uca_num_files.patch b/uca_num_files.patch new file mode 100644 index 000000000000..499d638dadd2 --- /dev/null +++ b/uca_num_files.patch @@ -0,0 +1,411 @@ +diff -ru Thunar-1.6.3.orig/plugins/thunar-uca/thunar-uca-editor.c Thunar-1.6.3/plugins/thunar-uca/thunar-uca-editor.c +--- Thunar-1.6.3.orig/plugins/thunar-uca/thunar-uca-editor.c 2013-05-21 19:50:07.000000000 -0700 ++++ Thunar-1.6.3/plugins/thunar-uca/thunar-uca-editor.c 2013-05-21 19:50:20.000000000 -0700 +@@ -63,6 +63,8 @@ + GtkWidget *sn_button; + GtkWidget *parameter_entry; + GtkWidget *patterns_entry; ++ GtkWidget *upper_button; ++ GtkWidget *lower_button; + GtkWidget *directories_button; + GtkWidget *audio_files_button; + GtkWidget *image_files_button; +@@ -102,6 +104,8 @@ + GtkWidget *table; + GtkWidget *hbox; + GtkWidget *vbox; ++ GtkWidget *spin; ++ GtkAdjustment *adj; + + /* configure the dialog properties */ + gtk_dialog_add_button (GTK_DIALOG (uca_editor), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); +@@ -381,6 +385,25 @@ + gtk_label_set_mnemonic_widget (GTK_LABEL (label), uca_editor->patterns_entry); + gtk_widget_show (uca_editor->patterns_entry); + ++ /* widgets for setting the upper and lower bounds */ ++ label = gtk_label_new ("Minimum number of files:"); ++ gtk_widget_show (label); ++ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); ++ adj = (GtkAdjustment *) gtk_adjustment_new (-1.0, -1.0, 9999.0, 1.0, 1.0, 0.0); ++ spin = gtk_spin_button_new (adj, 1.0, 0); ++ gtk_widget_show (spin); ++ gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); ++ uca_editor->lower_button = spin; ++ ++ label = gtk_label_new ("Maximum number of files:"); ++ gtk_widget_show (label); ++ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); ++ adj = (GtkAdjustment *) gtk_adjustment_new (-1.0, -1.0, 9999.0, 1.0, 1.0, 0.0); ++ spin = gtk_spin_button_new (adj, 1.0, 0); ++ gtk_widget_show (spin); ++ gtk_table_attach (GTK_TABLE (table), spin, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); ++ uca_editor->upper_button = spin; ++ + /* set Atk label relation for the entry */ + object = gtk_widget_get_accessible (uca_editor->patterns_entry); + relations = atk_object_ref_relation_set (gtk_widget_get_accessible (label)); +@@ -389,15 +412,15 @@ + g_object_unref (G_OBJECT (relation)); + + align = g_object_new (GTK_TYPE_ALIGNMENT, "height-request", 0, NULL); +- gtk_table_attach (GTK_TABLE (table), align, 0, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); ++ gtk_table_attach (GTK_TABLE (table), align, 0, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (align); + + label = g_object_new (GTK_TYPE_LABEL, "label", _("Appears if selection contains:"), "xalign", 0.0f, NULL); +- gtk_table_attach (GTK_TABLE (table), label, 0, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); ++ gtk_table_attach (GTK_TABLE (table), label, 0, 2, 4, 5, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (label); + + align = g_object_new (GTK_TYPE_ALIGNMENT, "left-padding", 18, NULL); +- gtk_table_attach (GTK_TABLE (table), align, 0, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); ++ gtk_table_attach (GTK_TABLE (table), align, 0, 2, 5, 6, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (align); + + itable = gtk_table_new (3, 2, TRUE); +@@ -431,11 +454,11 @@ + gtk_widget_show (uca_editor->other_files_button); + + align = g_object_new (GTK_TYPE_ALIGNMENT, "height-request", 12, NULL); +- gtk_table_attach (GTK_TABLE (table), align, 0, 2, 4, 5, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); ++ gtk_table_attach (GTK_TABLE (table), align, 0, 2, 6, 7, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (align); + + hbox = gtk_hbox_new (FALSE, 6); +- gtk_table_attach (GTK_TABLE (table), hbox, 0, 2, 5, 6, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); ++ gtk_table_attach (GTK_TABLE (table), hbox, 0, 2, 7, 8, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (hbox); + + image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DND); +@@ -746,6 +769,8 @@ + { + ThunarUcaTypes types; + gchar *description; ++ gchar *upper; ++ gchar *lower; + gchar *patterns; + gchar *command; + gchar *icon_name; +@@ -759,6 +784,8 @@ + /* determine the current values from the model */ + gtk_tree_model_get (GTK_TREE_MODEL (uca_model), iter, + THUNAR_UCA_MODEL_COLUMN_DESCRIPTION, &description, ++ THUNAR_UCA_MODEL_COLUMN_UPPER, &upper, ++ THUNAR_UCA_MODEL_COLUMN_LOWER, &lower, + THUNAR_UCA_MODEL_COLUMN_PATTERNS, &patterns, + THUNAR_UCA_MODEL_COLUMN_COMMAND, &command, + THUNAR_UCA_MODEL_COLUMN_TYPES, &types, +@@ -778,10 +805,14 @@ + gtk_entry_set_text (GTK_ENTRY (uca_editor->patterns_entry), (patterns != NULL) ? patterns : ""); + gtk_entry_set_text (GTK_ENTRY (uca_editor->command_entry), (command != NULL) ? command : ""); + gtk_entry_set_text (GTK_ENTRY (uca_editor->name_entry), (name != NULL) ? name : ""); ++ gtk_spin_button_set_value (GTK_SPIN_BUTTON (uca_editor->upper_button), (upper != NULL) ? g_strtod (upper, NULL) : -1.0); ++ gtk_spin_button_set_value (GTK_SPIN_BUTTON (uca_editor->lower_button), (lower != NULL) ? g_strtod (lower, NULL) : -1.0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (uca_editor->sn_button), startup_notify); + + /* cleanup */ + g_free (description); ++ g_free (upper); ++ g_free (lower); + g_free (patterns); + g_free (command); + g_free (icon_name); +@@ -804,10 +835,16 @@ + ThunarUcaModel *uca_model, + GtkTreeIter *iter) + { ++ gchar *upper_string; ++ gchar *lower_string; ++ + g_return_if_fail (THUNAR_UCA_IS_EDITOR (uca_editor)); + g_return_if_fail (THUNAR_UCA_IS_MODEL (uca_model)); + g_return_if_fail (iter != NULL); + ++ upper_string = g_strdup_printf ("%d", gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (uca_editor->upper_button))); ++ lower_string = g_strdup_printf ("%d", gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (uca_editor->lower_button))); ++ + thunar_uca_model_update (uca_model, iter, + gtk_entry_get_text (GTK_ENTRY (uca_editor->name_entry)), + NULL, /* don't touch the unique id */ +@@ -816,6 +853,8 @@ + gtk_entry_get_text (GTK_ENTRY (uca_editor->command_entry)), + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (uca_editor->sn_button)), + gtk_entry_get_text (GTK_ENTRY (uca_editor->patterns_entry)), ++ upper_string, ++ lower_string, + thunar_uca_editor_get_types (uca_editor)); + } + +diff -ru Thunar-1.6.3.orig/plugins/thunar-uca/thunar-uca-model.c Thunar-1.6.3/plugins/thunar-uca/thunar-uca-model.c +--- Thunar-1.6.3.orig/plugins/thunar-uca/thunar-uca-model.c 2013-05-21 19:50:07.000000000 -0700 ++++ Thunar-1.6.3/plugins/thunar-uca/thunar-uca-model.c 2013-05-21 19:53:41.000000000 -0700 +@@ -79,6 +79,8 @@ + PARSER_COMMAND, + PARSER_STARTUP_NOTIFY, + PARSER_PATTERNS, ++ PARSER_UPPER, ++ PARSER_LOWER, + PARSER_DESCRIPTION, + PARSER_DIRECTORIES, + PARSER_AUDIO_FILES, +@@ -169,6 +171,8 @@ + gchar *command; + guint startup_notify : 1; + gchar **patterns; ++ gchar *upper; ++ gchar *lower; + ThunarUcaTypes types; + + /* derived attributes */ +@@ -190,6 +194,8 @@ + GString *command; + GString *patterns; + GString *description; ++ GString *upper; ++ GString *lower; + gboolean startup_notify; + gboolean description_use; + guint description_match; +@@ -343,7 +349,13 @@ + + case THUNAR_UCA_MODEL_COLUMN_PATTERNS: + return G_TYPE_STRING; +- ++ ++ case THUNAR_UCA_MODEL_COLUMN_UPPER: ++ return G_TYPE_STRING; ++ ++ case THUNAR_UCA_MODEL_COLUMN_LOWER: ++ return G_TYPE_STRING; ++ + case THUNAR_UCA_MODEL_COLUMN_TYPES: + return G_TYPE_UINT; + +@@ -452,7 +464,15 @@ + str = g_strjoinv (";", item->patterns); + g_value_take_string (value, str); + break; +- ++ ++ case THUNAR_UCA_MODEL_COLUMN_UPPER: ++ g_value_set_static_string (value, item->upper); ++ break; ++ ++ case THUNAR_UCA_MODEL_COLUMN_LOWER: ++ g_value_set_static_string (value, item->lower); ++ break; ++ + case THUNAR_UCA_MODEL_COLUMN_TYPES: + g_value_set_uint (value, item->types); + break; +@@ -585,6 +605,8 @@ + parser.icon_name = g_string_new (NULL); + parser.command = g_string_new (NULL); + parser.patterns = g_string_new (NULL); ++ parser.upper = g_string_new (NULL); ++ parser.lower = g_string_new (NULL); + parser.description = g_string_new (NULL); + parser.startup_notify = FALSE; + parser.unique_id_generated = FALSE; +@@ -598,6 +620,8 @@ + /* cleanup */ + g_markup_parse_context_free (context); + g_string_free (parser.description, TRUE); ++ g_string_free (parser.upper, TRUE); ++ g_string_free (parser.lower, TRUE); + g_string_free (parser.patterns, TRUE); + g_string_free (parser.command, TRUE); + g_string_free (parser.icon_name, TRUE); +@@ -622,6 +646,8 @@ + { + /* release the previous values... */ + g_strfreev (item->patterns); ++ g_free (item->upper); ++ g_free (item->lower); + g_free (item->description); + g_free (item->command); + g_free (item->name); +@@ -679,6 +705,8 @@ + g_string_truncate (parser->unique_id, 0); + g_string_truncate (parser->command, 0); + g_string_truncate (parser->patterns, 0); ++ g_string_truncate (parser->upper, 0); ++ g_string_truncate (parser->lower, 0); + g_string_truncate (parser->description, 0); + xfce_stack_push (parser->stack, PARSER_ACTION); + } +@@ -736,6 +764,16 @@ + g_string_truncate (parser->patterns, 0); + xfce_stack_push (parser->stack, PARSER_PATTERNS); + } ++ else if (strcmp (element_name, "upper") == 0) ++ { ++ g_string_truncate (parser->upper, 0); ++ xfce_stack_push (parser->stack, PARSER_UPPER); ++ } ++ else if (strcmp (element_name, "lower") == 0) ++ { ++ g_string_truncate (parser->lower, 0); ++ xfce_stack_push (parser->stack, PARSER_LOWER); ++ } + else if (strcmp (element_name, "description") == 0) + { + for (n = 0; attribute_names[n] != NULL; ++n) +@@ -850,6 +888,8 @@ + parser->command->str, + parser->startup_notify, + parser->patterns->str, ++ parser->upper->str, ++ parser->lower->str, + parser->types); + + /* check if a new id should've been generated */ +@@ -884,7 +924,17 @@ + if (strcmp (element_name, "patterns") != 0) + goto unknown_element; + break; +- ++ ++ case PARSER_UPPER: ++ if (strcmp (element_name, "upper") != 0) ++ goto unknown_element; ++ break; ++ ++ case PARSER_LOWER: ++ if (strcmp (element_name, "lower") != 0) ++ goto unknown_element; ++ break; ++ + case PARSER_DESCRIPTION: + if (strcmp (element_name, "description") != 0) + goto unknown_element; +@@ -970,7 +1020,15 @@ + case PARSER_PATTERNS: + g_string_append_len (parser->patterns, text, text_len); + break; +- ++ ++ case PARSER_UPPER: ++ g_string_append_len (parser->upper, text, text_len); ++ break; ++ ++ case PARSER_LOWER: ++ g_string_append_len (parser->lower, text, text_len); ++ break; ++ + case PARSER_DESCRIPTION: + if (parser->description_use) + g_string_append_len (parser->description, text, text_len); +@@ -1099,6 +1157,7 @@ + GList *lp; + gint n_files; + gint i, m, n; ++ gint upper, lower; + + g_return_val_if_fail (THUNAR_UCA_IS_MODEL (uca_model), NULL); + g_return_val_if_fail (file_infos != NULL, NULL); +@@ -1140,7 +1199,16 @@ + { + /* check if we can just ignore this item */ + item = (ThunarUcaModelItem *) lp->data; +- if (!item->multiple_selection && n_files > 1) ++ upper = g_strtod(item->upper, NULL); ++ lower = g_strtod(item->lower, NULL); ++ ++ if (upper == -1) ++ upper = n_files; ++ ++ if (lower == -1) ++ lower = n_files; ++ ++ if (((!item->multiple_selection) && (n_files > 1)) || (n_files > upper) || (n_files < lower)) + continue; + + /* match the specified files */ +@@ -1316,6 +1384,8 @@ + const gchar *command, + gboolean startup_notify, + const gchar *patterns, ++ const gchar *upper, ++ const gchar *lower, + ThunarUcaTypes types) + { + ThunarUcaModelItem *item; +@@ -1336,6 +1406,10 @@ + item->icon_name = g_strdup (icon); + if (G_LIKELY (command != NULL && *command != '\0')) + item->command = g_strdup (command); ++ if (G_LIKELY (upper != NULL && *upper != '\0')) ++ item->upper = g_strdup (upper); ++ if (G_LIKELY (lower != NULL && *lower != '\0')) ++ item->lower = g_strdup (lower); + if (G_LIKELY (description != NULL && *description != '\0')) + item->description = g_strdup (description); + item->types = types; +@@ -1436,12 +1510,16 @@ + "\t<unique-id>%s</unique-id>\n" + "\t<command>%s</command>\n" + "\t<description>%s</description>\n" ++ "\t<upper>%s</upper>\n" ++ "\t<lower>%s</lower>\n" + "\t<patterns>%s</patterns>\n", + (item->icon_name != NULL) ? item->icon_name : "", + (item->name != NULL) ? item->name : "", + (item->unique_id != NULL) ? item->unique_id : "", + (item->command != NULL) ? item->command : "", + (item->description != NULL) ? item->description : "", ++ (item->upper != NULL) ? item->upper : "", ++ (item->lower != NULL) ? item->lower : "", + patterns); + fprintf (fp, "%s", escaped); + g_free (patterns); +diff -ru Thunar-1.6.3.orig/plugins/thunar-uca/thunar-uca-model.h Thunar-1.6.3/plugins/thunar-uca/thunar-uca-model.h +--- Thunar-1.6.3.orig/plugins/thunar-uca/thunar-uca-model.h 2013-05-21 19:50:07.000000000 -0700 ++++ Thunar-1.6.3/plugins/thunar-uca/thunar-uca-model.h 2013-05-21 19:50:20.000000000 -0700 +@@ -44,6 +44,8 @@ + THUNAR_UCA_MODEL_COLUMN_UNIQUE_ID, + THUNAR_UCA_MODEL_COLUMN_COMMAND, + THUNAR_UCA_MODEL_COLUMN_STARTUP_NOTIFY, ++ THUNAR_UCA_MODEL_COLUMN_UPPER, ++ THUNAR_UCA_MODEL_COLUMN_LOWER, + THUNAR_UCA_MODEL_COLUMN_PATTERNS, + THUNAR_UCA_MODEL_COLUMN_TYPES, + THUNAR_UCA_MODEL_COLUMN_STOCK_LABEL, +@@ -96,6 +98,8 @@ + const gchar *command, + gboolean startup_notify, + const gchar *patterns, ++ const gchar *upper, ++ const gchar *lower, + ThunarUcaTypes types); + + gboolean thunar_uca_model_save (ThunarUcaModel *uca_model, +diff -ru Thunar-1.6.3.orig/plugins/thunar-uca/uca.xml.in Thunar-1.6.3/plugins/thunar-uca/uca.xml.in +--- Thunar-1.6.3.orig/plugins/thunar-uca/uca.xml.in 2013-05-21 19:50:07.000000000 -0700 ++++ Thunar-1.6.3/plugins/thunar-uca/uca.xml.in 2013-05-21 19:50:20.000000000 -0700 +@@ -40,6 +40,8 @@ + <action> + <icon>utilities-terminal</icon> + <patterns>*</patterns> ++ <lower>-1</lower> ++ <upper>-1</upper> + <_name>Open Terminal Here</_name> + <command>exo-open --working-directory %f --launch TerminalEmulator</command> + <_description>Example for a custom action</_description> +@@ -47,4 +49,15 @@ + <directories/> + </action> + ++ <action> ++ <icon>preferences-desktop-wallpaper</icon> ++ <patterns>*</patterns> ++ <lower>0</lower> ++ <upper>1</upper> ++ <_name>Set as wallpaper</_name> ++ <command>xfconf-query -c xfce4-desktop -p /backdrop/screen0/monitor0/image-path --create -t string -s \"%f\"</command> ++ <_description>Implementing the entire wallpaper plugin with just a bit of XML</_description> ++ <image-files/> ++ </action> ++ + </actions> |