[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#988850: buster-pu: package thunar/1.8.17-1



Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu
X-Debbugs-Cc: xfce-devel@lists.debian.org

Hi release team

this is a pre-approval request for updating Thunar in stable, from 1.8.4
to 1.8.17.

The context is the recently found vulnerability CVE-2021-32563
(#988394), which has been fixed in 1.8.17.

With my security team hat on, I don't think it really desserves a DSA
with an isolated fix, but (with my Xfce maintainer hat on) I think it
would make sense to fix it in a point update, along with the various
bugfixes and translation updates that Thunar had since the freeze.

I've not yet done the packaging work (so I don't mess my local
repository) but the diff between the two upstream tags is attached.

Thanks in advance,
-- 
Yves-Alexis
diff --git a/.gitignore b/.gitignore
index 9fbb0a34..7c510800 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,7 @@ core
 *.service
 *.policy
 org.xfce.thunar.appdata.xml
+thunar.appdata.xml
 gtk-doc.make
 ThunarBulkRename
 Thunar.spec
@@ -109,6 +110,7 @@ thunar/thunar-dbus-freedesktop-interfaces.[ch]
 thunar/thunar-dbus-service-infos.[ch]
 thunar/thunar-fallback-icon.c
 thunar/thunar-thumbnail-cache-proxy.[ch]
+thunar/thunar-thumbnail-frame.c
 thunar/thunar-thumbnailer-manager-proxy.h
 thunar/thunar-thumbnailer-proxy.[ch]
 thunar/thunar-marshal.[ch]
diff --git a/HACKING b/HACKING
index ca01ce77..4c0d0aac 100644
--- a/HACKING
+++ b/HACKING
@@ -1,7 +1,7 @@
 Bug tracking system
 ===================
 
-Thunar uses the Xfce bug tracking system at http://bugzilla.xfce.org/,
+Thunar uses the Xfce bug tracking system at https://bugzilla.xfce.org/,
 hosted and maintained by the Xfce project.
 
 
@@ -23,7 +23,7 @@ Feature requests
 ================
 
 Please file feature requests to the Xfce bug tracking system
-(http://buzilla.xfce.org, product Thunar) with a Severity of
+(https://buzilla.xfce.org, product Thunar) with a Severity of
 enhancement. Make sure that your feature request wasn't reported
 already before; requesting a feature several times won't increase
 the changed that it gets added!
diff --git a/Makefile.am b/Makefile.am
index cb2db7a0..f43aac8d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -61,9 +61,8 @@ ThunarBulkRename: ThunarBulkRename.in Makefile
 
 desktopdir = $(datadir)/applications
 desktop_in_in_files = 							\
-	Thunar.desktop.in.in						\
-	Thunar-bulk-rename.desktop.in.in				\
-	Thunar-folder-handler.desktop.in.in
+	thunar.desktop.in.in						\
+	thunar-bulk-rename.desktop.in.in
 desktop_in_files = $(desktop_in_in_files:.desktop.in.in=.desktop.in)
 %.desktop.in: %.desktop.in.in Makefile
 	$(AM_V_GEN) $(SED) -e "s,\@HELPERDIR\@,$(HELPER_PATH_PREFIX),g" < $< > $@
diff --git a/NEWS b/NEWS
index ae435d21..f0022ffd 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,231 @@
+1.8.17
+======
+- Dont execute files, passed via command line due to security risks
+  That Fixes CVE-2021-32563
+
+- Fix combo box entry order (Issue #435)
+- Translation Updates:
+  Albanian, Amharic, Arabic, Armenian, Armenian (Armenia), Asturian,
+  Basque, Belarusian, Bengali, Bulgarian, Catalan, Chinese (China),
+  Chinese (Hong Kong), Chinese (Taiwan), Croatian, Czech, Danish,
+  Dutch, Eastern Armenian, English (Australia), English (United
+  Kingdom), Esperanto, Estonian, Finnish, French, Galician, German,
+  Greek, Hebrew, Hungarian, Icelandic, Indonesian, Interlingue,
+  Italian, Japanese, Kazakh, Korean, Latvian, Lithuanian, Malay,
+  Norwegian Bokmål, Norwegian Nynorsk, Occitan (post 1500), Panjabi
+  (Punjabi), Persian (Iran), Polish, Portuguese, Portuguese (Brazil),
+  Romanian, Russian, Serbian, Slovak, Spanish, Swedish, Telugu, Thai,
+  Turkish, Ukrainian, Urdu, Urdu (Pakistan), Vietnamese
+
+1.8.16
+======
+- Add missing parameter to ThunarBrowserPokeDeviceFunc function
+- Fix error for custom date format in details view (issue #389)
+- Fix unavailable rubber banding in detailed view (Issue #326)
+- Ghost file ocasionally remains when dropping file into directory (Fixes #312)
+- Translation Updates:
+  Albanian, Armenian, Armenian (Armenia), Basque, Belarusian, Chinese 
+  (China), Chinese (Hong Kong), Croatian, Eastern Armenian, Esperanto, 
+  Estonian, Finnish, French, Hebrew, Hungarian, Indonesian, Interlingue, 
+  Italian, Kazakh, Korean, Lithuanian, Portuguese, Slovak, Swedish,
+
+1.8.15
+======
+- Only open devices after successful mount attempt (Bug #16831)
+- Fix shortcut support for addressbar (Bug #4537 and Bug #13680)
+- Fix crash in bulk renamer on repeated rename (Bug #16824)
+- Add checks for thumbnailer 0 handles (Bug #14122)
+- Replace 'thunar_return_if_fail (THUNAR_IS_DEVICE (device))' with 
+standard 'if (..)' to prevent possible crashes. (Bug #13404)
+- Fix check if folder is fully loaded when expanding path in tree view. 
+Prevents 100% CPU load and loosing sync with main view in some cases.
+(Bug #15762)
+- Fixes 100%CPU on tree-view in some rare cases (Bug #16024)
+- Delete native files faster (Bug #16641)
+- Support libxfce4ui XfceTitledDialog new API (Bug #16616)
+- Translation Updates:
+  Albanian, Amharic, Arabic, Armenian, Armenian (Armenia), Basque, 
+  Belarusian, Bengali, Bulgarian, Catalan, Chinese (China), Chinese (Hong 
+  Kong), Chinese (Taiwan), Croatian, Czech, Danish, Dutch, English 
+  (Australia), English (United Kingdom), Esperanto, Estonian, Finnish, 
+  French, Galician, German, Greek, Hebrew, Hungarian, Icelandic, 
+  Indonesian, Interlingue, Italian, Japanese, Kazakh, Korean, Latvian, 
+  Lithuanian, Malay, Norwegian Bokmål, Norwegian Nynorsk, Occitan (post 
+  1500), Panjabi (Punjabi), Persian (Iran), Polish, Portuguese, 
+  Portuguese (Brazil), Romanian, Russian, Serbian, Slovak, Spanish, 
+  Swedish, Telugu, Thai, Turkish, Uighur, Ukrainian, Urdu, Urdu 
+  (Pakistan), Vietnamese
+
+1.8.14
+======
+- Revert "Allow opening of multiple file selections (bug #2487)", 
+because it introduced a regression (Not possible any more to DnD 
+multiple files in icon/compact view)
+- Translation Updates: Portuguese
+
+1.8.13
+======
+- Use tre-view toplevel path of the cursor, if available, in order to 
+prevent jumping (Bug #16024)
+- Increase vertical gap between icon and its label slightly (Bug #16041)
+- Fix crash when inserting USB device in tree-view  mode. (Bug #15172)
+- Fix jump to Home when ejecting a currently viewed device (Bug #16504)
+- Allow context menu when editing location in pathbar (Bug #16483)
+- Sort device entries in tree view (Bug #16471)
+- Allow to open multiple files at once (Bug #2487)
+- Fix incorrect pathbar autocomplete (Bug #16267)
+- Avoid unreadable names in detailed view (Bug #16391)
+- Prevent crash when renaming files (Bug #10805)
+- Translation Updates:
+  Belarusian, Croatian, Finnish, French, Hebrew, Indonesian, Kazakh, 
+  Malay, Portuguese, Portuguese (Brazil)
+
+1.8.12
+======
+- NULL is the proper sentinel for g_object_new() (Bug #16310)
+- Drop timer on finalize (Bug #15305)
+- Store column width setting asynchronously and only once (Bug #15305)
+- When move to trash fails, ask whether to delete files (Bug #15975)
+- Ctrl+Mousewheel does not enlarge/shrink entries (for detailed list 
+view) (Bug #15936)
+- Extra padding for Eject button when scrollbar is visible (Bug #15312)
+- Use standard icon instead of custom
+- Translation Updates: Albanian, Chinese (China), Chinese (Taiwan), Croatian,
+  Czech, Dutch, French, Galician, Greek, Hungarian, Italian, Japanese,
+  Norwegian Bokmål, Portuguese, Portuguese (Brazil), Russian, Serbian, Slovak,
+  Spanish, Swedish, Ukrainian
+
+1.8.11
+======
+- Thunar 1.8.10 crashing on startup in FreeBSD and Fedora, caused by 
+nonfunctional pango version check (Bug #16136, Bug #16138)
+- Translation Updates:
+Interlingue, Spanish
+
+1.8.10
+======
+- Allow compilation with panel 4.15
+- thunar-job: callee should keep track of the number of processed files 
+(Bug #16117)
+- Thunar does not show a context menu on right-click when started via 
+trash-panel-plugin (Bug #16000)
+- Make sure icon text is centered after unchecking "Text beside icons"
+- Remove the vertical gap between icon and its label (Bug #16041)
+- Fix icon view alignment (Bug #16107)
+- Not possible to grab scrollbar on the very right pixels when Thunar 
+is maximized (Bug #16050)
+- Wrap text of error dialog
+- Not possible to empty the trash via the pathbar context menu
+- Crash on refresh if remote folder has been removed (Bug #15961)
+- Center action buttons in conflict dialog window (Bug #15973) - 
+Prevent usage of deprecated gtk_dialog_get_action_area
+- Ensure user customizable action uses currently selected file path (Bug #15119)
+- make filename label selectable in conflict dialog window
+- Center action buttons in conflict dialog window (Bug #15973)
+- Clear user customizable action shortcut when the action is deleted
+- Prevent Gtk-CRITICAL when adding or modifying a user customizable action.
+- Thunar SendTo Email: Add missing archive formats for archive 
+detection (Bug #15917)
+- sendto plugin: fix content type resolution. (Bug #15916)
+- sendto plugin: extract function tse_file_is_archive (Bug #15916)
+- sendto plugin: move g_file_info_get_content_type() call out of the 
+cycle (Bug #15916)
+- All glory to lowercase (Bug #15394)
+- mismatched names between thunar.appdata.xml and thunar.desktop (Bug #15498)
+- Replace text "Enter the new name:" by "Enter the name:" for file 
+creation dialog (Bug #15423)
+- Remove superfluous .desktop file "Thunar-folder-handler.desktop.in" 
+(Bug #15467)
+- Prevent unnecessary fallback copy-delete in file move when overwriting
+- Fix possible memory leak
+- Fix popup menus size (Bug #15832)
+- Add Alt+D as alternative accelerator for Open Location (Bug #15828)
+- Do not insert hyphens at intra-word line breaks (Bug #15856)
+- Translation Updates:
+  Albanian, Arabic, Belarusian, Bulgarian, Catalan, Chinese (Taiwan), 
+  Croatian, Danish, Dutch, English (United Kingdom), French, Galician, 
+  German, Hungarian, Italian, Japanese, Korean, Lithuanian, Malay, 
+  Norwegian Bokmål, Persian (Iran), Polish, Portuguese, Portuguese 
+  (Brazil), Russian, Serbian, Slovak, Slovenian, Spanish, Thai, Turkish, 
+  Ukrainian
+
+1.8.9
+======
+- Remove 'auto-expand folders' from tree-view since it causes bad
+usability with keyboard (Bug #15743)
+- preferences: Add button icons to Help/Close
+- Use designated initializer to avoid compile warnings (Bug #15734)
+- Prevent premature disposal of clipboard manager (Bug #15635)
+- Keep "Open with" menu items updated (Bug #15530)
+- Translation Updates: Norwegian Bokmål, Norwegian Nynorsk, Portuguese,
+Portuguese (Brazil), Turkish
+
+1.8.8
+=====
+- Do not register "send to" as last used app (Bug #14118)
+- Use https where possible
+- Dont restart the folder monitor on each refresh (Bug #13364)
+- Fix XML declaratation in uca.xml (Bug #13623)
+- Always show the executable checkbox (Bug #15605)
+- Replace Trash action with Delete as needed (Bug #15352)
+- Translation updates: Armenian, Finnish, Kazakh,
+Portuguese (Brazil), Swedish, Thai, Turkish
+
+1.8.7
+=====
+- Fix crash on unmounted volume in tree pane right click (Bug #15452)
+- Do not check G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE anymore (Bug #15367)
+- Deactivate "Move to Trash" menu entry on volumes without trash (Bug #15352)
+- thunar-sendto-email.desktop: use xdg mail-send icon
+- Restore "Empty File" menu icon (Bug #15540)
+- Rename Camelcase to Title Case (Bug #15579)
+- Update mimeapps.list only when necessary (Bug #15533)
+- Prevent new bookmarks on sidebar when dragging files (Bug #14921)
+- Translation updates: Albanian, Armenian (Armenia), Belarusian, Catalan,
+Chinese (China), Chinese (Taiwan), Croatian, Czech, Danish,
+English (Australia), Finnish, French, Galician, German, Hebrew, Hungarian,
+Interlingue, Italian, Japanese, Malay, Norwegian Nynorsk, Portuguese, Russian,
+Serbian, Spanish, Thai, Turkish
+
+1.8.6
+=====
+- Job is now optional for thunar_io_scan_directory
+- Expand scroll window of file operation progress dialog (Bug #14946)
+- Fix compiler error -Wcast-function-type (GCC 8)
+- Bump glib minimal required version
+- Fix g_type_class_add_private is deprecated
+- Small code cleanup
+- Fix pathbar to on middle click open folders in new tabs (Bug #15302)
+- Translation updates: Danish
+
+1.8.5
+=====
+- Do not exit when dbus name registration fails (Bug #15149)
+- tree view jumps (scrolls) when clicking on a directory (Bug #15174)
+- Correctly check if destination is writable (Bug #14718)
+- Make tree-view 'Move to Trash' icon the same as in main pane
+- Make toggle for the delete entry affect tree-view side pane too
+- Pathbar buttons are now resized on folder rename (#15024)
+- Load templates synchronously (Bug #15200)
+- delete key in tree-view can delete the user home folder (Bug #15095)
+- Hide unneeded context menu entries for folder "Trash" in tree view
+- crash after clicking when XDG_SESSION_TYPE isn't set (Bug #15366)
+- man page incorrectly suggests '-v' instead of '-V'
+- Fix how wallpaper is set on Gnome
+- SEGV (11) on USB-flash connection (Bug #13813)
+- Fix session startup priority
+- Fix queued context menu popup
+- Restore right-click drag and drop functionality (Bug #14583)
+- Translation updates: Albanian, Amharic, Arabic, Asturian, Basque, Belarusian,
+Bengali, Bulgarian, Catalan, Chinese (China), Chinese (Hong Kong SAR China),
+Chinese (Taiwan), Croatian, Czech, Danish, Dutch, English (Australia),
+English (United Kingdom), Esperanto, Estonian, Finnish, French, Galician,
+German, Greek, Hebrew, Hungarian, Icelandic, Indonesian, Interlingue, Italian,
+Japanese, Kazakh, Korean, Latvian, Lithuanian, Malay, Norwegian Bokmål,
+Norwegian Nynorsk, Occitan, Persian (Iran), Polish, Portuguese,
+Portuguese (Brazil), Punjabi, Romanian, Russian, Serbian, Slovak, Slovenian,
+Spanish, Swedish, Telugu, Thai, Turkish, Urdu, Urdu (Pakistan), Uyghur, Vietnamese
+
 1.8.4
 =====
 - renamed org.freedesktop.FileManager1.service.in to
diff --git a/README b/README
index 4ab6c1b4..be4ca73d 100644
--- a/README
+++ b/README
@@ -60,32 +60,32 @@ Standards compliance
 Thunar supports the following standards/specifications:
 
   * XDG Base Directory Specification
-    http://freedesktop.org/wiki/Standards_2fbasedir_2dspec
+    https://freedesktop.org/wiki/Specifications/basedir-spec
 
   * Shared MIME Database Specification
-    http://freedesktop.org/wiki/Standards_2fshared_2dmime_2dinfo_2dspec
+    https://freedesktop.org/wiki/Specifications/shared-mime-info-spec
 
   * X Direct Save (XDS) Protocol for the X Window System
-    http://freedesktop.org/wiki/Standards_2fdirect_2dsave
+    https://freedesktop.org/wiki/Specifications/direct-save
 
   * Icon Theme Specification
-    http://freedesktop.org/wiki/Standards_2ficon_2dtheme_2dspec
+    https://freedesktop.org/wiki/Specifications/icon-theme-spec
 
   * Thumbnail Managing Standard
-    http://jens.triq.net/thumbnail-spec/index.html
+    https://freedesktop.org/wiki/Specifications/thumbnails
 
   * File URI Specification
-    http://freedesktop.org/wiki/Standards_2ffile_2duri_2dspec
+    https://freedesktop.org/wiki/Specifications/file-uri-spec
 
   * Desktop Trash Can Specification
-    http://freedesktop.org/wiki/Standards_2ftrash_2dspec
+    https://freedesktop.org/wiki/Specifications/trash-spec
 
 
 How to report bugs?
 ===================
 
 Bugs should be reported to the Xfce bug tracking system
-(http://bugzilla.xfce.org, product Thunar). You will need to
+(https://bugzilla.xfce.org, product Thunar). You will need to
 create an account for yourself.
 
 Please read the HACKING file for information on where to send
diff --git a/Thunar-folder-handler.desktop.in.in b/Thunar-folder-handler.desktop.in.in
deleted file mode 100644
index c3865c47..00000000
--- a/Thunar-folder-handler.desktop.in.in
+++ /dev/null
@@ -1,15 +0,0 @@
-[Desktop Entry]
-_Name=Open Folder with Thunar
-_Comment=Open the specified folders in Thunar
-_GenericName=Open Folder
-TryExec=Thunar
-Exec=thunar %F
-Icon=Thunar
-NoDisplay=true
-Terminal=false
-StartupNotify=true
-Type=Application
-Categories=System;Utility;Core;GTK;FileTools;FileManager;
-MimeType=inode/directory;
-
-# vi:set encoding=UTF-8:
diff --git a/autogen.sh b/autogen.sh
index e5e6f6b8..2c6f7940 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -24,7 +24,7 @@
 autogen.sh: You don't seem to have the Xfce development tools installed on
             your system, which are required to build this software.
             Please install the xfce4-dev-tools package first, it is available
-            from http://www.xfce.org/.
+            from https://www.xfce.org/.
 EOF
   exit 1
 }
diff --git a/configure.ac.in b/configure.ac.in
index 067af58e..31a5170f 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -26,7 +26,7 @@ m4_define([thunarx_verinfo], [0:0:0])
 m4_define([thunarx_version_api], [3])
 m4_define([thunar_version_major], [1])
 m4_define([thunar_version_minor], [8])
-m4_define([thunar_version_micro], [4])
+m4_define([thunar_version_micro], [17])
 m4_define([thunar_version_nano], [])
 m4_define([thunar_version_build], [@REVISION@])
 m4_define([thunar_version_tag], [])
@@ -40,8 +40,8 @@ m4_define([thunar_debug_default], [ifelse(thunar_version_tag(), [git], [yes], [m
 dnl ***************************
 dnl *** Initialize autoconf ***
 dnl ***************************
-AC_COPYRIGHT([Copyright (c) 2004-2015 The Thunar development team. All rights reserved.])
-AC_INIT([Thunar], [thunar_version], [http://bugzilla.xfce.org/], [Thunar])
+AC_COPYRIGHT([Copyright (c) 2004-2019 The Thunar development team. All rights reserved.])
+AC_INIT([thunar], [thunar_version], [https://bugzilla.xfce.org/], [thunar])
 AC_PREREQ([2.60])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CANONICAL_TARGET()
@@ -146,16 +146,17 @@ dnl ***********************************
 dnl *** Check for required packages ***
 dnl ***********************************
 XDT_CHECK_PACKAGE([EXO], [exo-2], [0.12.0])
-XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.30.0])
-XDT_CHECK_PACKAGE([GIO], [gio-2.0], [2.30.0])
-XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.30.0])
-XDT_CHECK_PACKAGE([GMODULE], [gmodule-2.0], [2.30.0])
+XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.42.0])
+XDT_CHECK_PACKAGE([GIO], [gio-2.0], [2.42.0])
+XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.42.0])
+XDT_CHECK_PACKAGE([GMODULE], [gmodule-2.0], [2.42.0])
 XDT_CHECK_PACKAGE([GTK], [gtk+-3.0], [3.22.0])
 XDT_CHECK_PACKAGE([GDK_PIXBUF], [gdk-pixbuf-2.0], [2.14.0])
 XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.12.0])
 XDT_CHECK_PACKAGE([LIBXFCE4UI], [libxfce4ui-2], [4.12.0])
 XDT_CHECK_PACKAGE([LIBXFCE4KBD_PRIVATE], [libxfce4kbd-private-3], [4.12.0])
 XDT_CHECK_PACKAGE([XFCONF], [libxfconf-0], [4.12.0])
+XDT_CHECK_PACKAGE([PANGO], [pango], [1.38.0])
 
 dnl ******************************
 dnl *** GObject Instrospection ***
diff --git a/docs/Thunar.xml b/docs/Thunar.xml
index a2281744..531e1a5e 100644
--- a/docs/Thunar.xml
+++ b/docs/Thunar.xml
@@ -48,9 +48,9 @@
   <refsect1>
     <title>Invocation</title>
     <para>
-      <command>Thunar</command> takes a list of <replaceable>URI</replaceable>s for folders that should be
-      opened in new file manager windows or files that should be run using the default application for their
-      types. The <replaceable>URI</replaceable>s may be specified as either <emphasis role="bold">file:</emphasis>
+      <command>Thunar</command> takes a list of <replaceable>URI</replaceable>s for files/folders that should be
+      opened in new file manager windows.
+      The <replaceable>URI</replaceable>s may be specified as either <emphasis role="bold">file:</emphasis>
       or <emphasis role="bold">trash:</emphasis> URIs, absolute paths or paths relative to the current directory
       from which <command>Thunar</command> is being invoked. If no <replaceable>URI</replaceable>s are specified,
       the current folder will be opened in a new file manager window.
@@ -72,7 +72,7 @@
         </varlistentry>
 
         <varlistentry>
-          <term><option>-v</option>, <option>--version</option></term>
+          <term><option>-V</option>, <option>--version</option></term>
           <listitem>
             <para>Print version information and exit.</para>
           </listitem>
diff --git a/docs/reference/thunarx/thunarx-docs.xml b/docs/reference/thunarx/thunarx-docs.xml
index d41bb2b5..4a1f2cbe 100644
--- a/docs/reference/thunarx/thunarx-docs.xml
+++ b/docs/reference/thunarx/thunarx-docs.xml
@@ -42,7 +42,7 @@
         any later version published by the Free Software Foundation; with no
         Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
         Texts. The complete license text is available from the <ulink
-        type="http" url="http://www.gnu.org/";>Free Software Foundation</ulink>.
+        type="http" url="https://www.gnu.org/";>Free Software Foundation</ulink>.
       </para>
     </legalnotice>
 
@@ -80,7 +80,7 @@
 
     <para>
       It is based on the <ulink type="http"
-      url="http://library.gnome.org/devel/gobject/unstable/chapter-gtype.html";>GLib Dynamic Type
+      url="https://developer.gnome.org/gobject/unstable/chapter-gtype.html";>GLib Dynamic Type
       System</ulink> and loads the extensions on demand to reduce the system resources
       allocated for the file manager process.
     </para>
@@ -106,7 +106,7 @@
 
         <listitem>
           Provide basic compatibility with the <ulink type="http"
-          url="http://www.gnome.org/projects/nautilus/";>Nautilus</ulink> Extension Framework,
+          url="https://www.gnome.org/projects/nautilus/";>Nautilus</ulink> Extension Framework,
           so vendors don't need to write several versions of their extensions for the various
           file managers. With the current implementation it should be easy to write a small
           wrapper library for generic extensions that can be loaded into both Thunar and
@@ -119,10 +119,10 @@
           therefore people that already know how to write Nautilus extensions must be
           careful when writing extensions for Thunar, because Thunar actually unloads the
           extension when it's no longer needed. The <ulink type="http"
-          url="http://library.gnome.org/devel/gobject/unstable/GTypePlugin.html";>GTypePlugin</ulink>
+          url="https://developer.gnome.org/gobject/unstable/GTypePlugin.html";>GTypePlugin</ulink>
           and <ulink type="http"
-          url="http://library.gnome.org/devel/gobject/unstable/GTypeModule.html";>GTypeModule</ulink>
-          sections in the <ulink type="http" url="http://library.gnome.org/devel/gobject/unstable/";>GObject
+          url="https://developer.gnome.org/gobject/unstable/GTypeModule.html";>GTypeModule</ulink>
+          sections in the <ulink type="http" url="https://developer.gnome.org/gobject/unstable/";>GObject
           Reference Manual</ulink> provide details about the handling of dynamic type plugins.
         </listitem>
 
diff --git a/icons/16x16/Makefile.am b/icons/16x16/Makefile.am
index d121bf65..dfbd9507 100644
--- a/icons/16x16/Makefile.am
+++ b/icons/16x16/Makefile.am
@@ -4,9 +4,8 @@ apps_DATA =								\
 
 stockdir = $(datadir)/icons/hicolor/16x16/stock/navigation
 stock_DATA =								\
-	stock_folder-copy.png						\
-	stock_folder-move.png						\
-	stock_thunar-shortcuts.png
+	stock_folder-copy.png					\
+	stock_folder-move.png
 
 EXTRA_DIST =								\
 	$(apps_DATA)							\
diff --git a/icons/16x16/stock_thunar-shortcuts.png b/icons/16x16/stock_thunar-shortcuts.png
deleted file mode 100644
index 59e04f27..00000000
Binary files a/icons/16x16/stock_thunar-shortcuts.png and /dev/null differ
diff --git a/org.xfce.thunar.appdata.xml.in b/org.xfce.thunar.appdata.xml.in
index 64a13577..272f6d72 100644
--- a/org.xfce.thunar.appdata.xml.in
+++ b/org.xfce.thunar.appdata.xml.in
@@ -14,12 +14,12 @@
       clean two-pane design for browsing all your files.
     </_p>
   </description>
-  <url type="homepage">http://xfce.org/projects</url>
+  <url type="homepage">https://xfce.org/projects</url>
   <url type="bugtracker">https://bugzilla.xfce.org/describecomponents.cgi?product=Thunar</url>
-  <url type="help">http://docs.xfce.org/xfce/thunar/start</url>
+  <url type="help">https://docs.xfce.org/xfce/thunar/start</url>
 
   <screenshots>
-    <screenshot type="default">http://docs.xfce.org/_media/xfce/thunar/file-manager-window.png</screenshot>
+    <screenshot type="default">https://docs.xfce.org/_media/xfce/thunar/file-manager-window.png</screenshot>
   </screenshots>
 
   <categories>
diff --git a/org.xfce.thunar.policy.in.in b/org.xfce.thunar.policy.in.in
index d64113e9..6caf6d06 100644
--- a/org.xfce.thunar.policy.in.in
+++ b/org.xfce.thunar.policy.in.in
@@ -13,7 +13,7 @@
  -->
 
  <vendor>Thunar</vendor>
- <vendor_url>http://xfce.org/</vendor_url>
+ <vendor_url>https://xfce.org/</vendor_url>
  <icon_name>system-file-manager</icon_name>
 
 
diff --git a/plugins/thunar-apr/thunar-apr-image-page.c b/plugins/thunar-apr/thunar-apr-image-page.c
index 5a846192..20e14ce5 100644
--- a/plugins/thunar-apr/thunar-apr-image-page.c
+++ b/plugins/thunar-apr/thunar-apr-image-page.c
@@ -108,8 +108,8 @@ thunar_apr_image_page_init (ThunarAprImagePage *image_page)
   AtkObject      *object;
   GtkWidget      *label;
   GtkWidget      *grid;
-  GtkWidget      *spacer;
 #ifdef HAVE_EXIF
+  GtkWidget      *spacer;
   guint           n;
 #endif
 
diff --git a/plugins/thunar-sbr/thunar-sbr-case-renamer.c b/plugins/thunar-sbr/thunar-sbr-case-renamer.c
index c5847b88..86f9c2a0 100644
--- a/plugins/thunar-sbr/thunar-sbr-case-renamer.c
+++ b/plugins/thunar-sbr/thunar-sbr-case-renamer.c
@@ -184,7 +184,7 @@ thunar_sbr_case_renamer_set_property (GObject      *object,
 
 static gchar*
 tscr_utf8_strcase (const gchar *text,
-                   gboolean     camelcase)
+                   gboolean     title_case)
 {
   const gchar *t;
   gboolean     upper = TRUE;
@@ -199,8 +199,7 @@ tscr_utf8_strcase (const gchar *text,
     {
       /* check the next char */
       c = g_utf8_get_char (t);
-      if (camelcase
-          && g_unichar_isspace (c))
+      if (title_case && g_unichar_isspace (c))
         {
           upper = TRUE;
         }
@@ -239,7 +238,7 @@ thunar_sbr_case_renamer_process (ThunarxRenamer  *renamer,
     case THUNAR_SBR_CASE_RENAMER_MODE_UPPER:
       return g_utf8_strup (text, -1);
 
-    case THUNAR_SBR_CASE_RENAMER_MODE_CAMEL:
+    case THUNAR_SBR_CASE_RENAMER_MODE_TITLE:
       return tscr_utf8_strcase (text, TRUE);
 
    case THUNAR_SBR_CASE_RENAMER_MODE_FIRST_UPPER:
diff --git a/plugins/thunar-sbr/thunar-sbr-enum-types.c b/plugins/thunar-sbr/thunar-sbr-enum-types.c
index 1368cee8..cad6b648 100644
--- a/plugins/thunar-sbr/thunar-sbr-enum-types.c
+++ b/plugins/thunar-sbr/thunar-sbr-enum-types.c
@@ -92,7 +92,7 @@ thunar_sbr_register_enum_types (ThunarxProviderPlugin *plugin)
   {
     { THUNAR_SBR_CASE_RENAMER_MODE_LOWER,       "THUNAR_SBR_CASE_RENAMER_MODE_LOWER",       N_ ("lowercase"),                 },
     { THUNAR_SBR_CASE_RENAMER_MODE_UPPER,       "THUNAR_SBR_CASE_RENAMER_MODE_UPPER",       N_ ("UPPERCASE"),                 },
-    { THUNAR_SBR_CASE_RENAMER_MODE_CAMEL,       "THUNAR_SBR_CASE_RENAMER_MODE_CAMEL",       N_ ("Camelcase"),                 },
+    { THUNAR_SBR_CASE_RENAMER_MODE_TITLE,       "THUNAR_SBR_CASE_RENAMER_MODE_TITLE",       N_ ("Title Case"),                 },
     { THUNAR_SBR_CASE_RENAMER_MODE_FIRST_UPPER, "THUNAR_SBR_CASE_RENAMER_MODE_FIRST_UPPER", N_ ("First character uppercase"), },
     { 0,                                        NULL,                                       NULL,                             },
   };
diff --git a/plugins/thunar-sbr/thunar-sbr-enum-types.h b/plugins/thunar-sbr/thunar-sbr-enum-types.h
index db89e62c..6300b035 100644
--- a/plugins/thunar-sbr/thunar-sbr-enum-types.h
+++ b/plugins/thunar-sbr/thunar-sbr-enum-types.h
@@ -31,7 +31,7 @@ G_BEGIN_DECLS;
  * ThunarSbrCaseRenamerMode:
  * @THUNAR_SBR_CASE_RENAMER_MODE_LOWER       : convert to lower case.
  * @THUNAR_SBR_CASE_RENAMER_MODE_UPPER       : convert to upper case.
- * @THUNAR_SBR_CASE_RENAMER_MODE_CAMEL       : convert to camel case.
+ * @THUNAR_SBR_CASE_RENAMER_MODE_TITLE       : convert to title case.
  * @THUNAR_SBR_CASE_RENAMER_MODE_FIRST_UPPER : convert to First character uppercase.
  *
  * The operation mode for the #ThunarSbrCaseRenamer.
@@ -40,7 +40,7 @@ typedef enum
 {
   THUNAR_SBR_CASE_RENAMER_MODE_LOWER,
   THUNAR_SBR_CASE_RENAMER_MODE_UPPER,
-  THUNAR_SBR_CASE_RENAMER_MODE_CAMEL,
+  THUNAR_SBR_CASE_RENAMER_MODE_TITLE,
   THUNAR_SBR_CASE_RENAMER_MODE_FIRST_UPPER,
 } ThunarSbrCaseRenamerMode;
 
diff --git a/plugins/thunar-sendto-email/main.c b/plugins/thunar-sendto-email/main.c
index 587cdd88..4e1ee0c2 100644
--- a/plugins/thunar-sendto-email/main.c
+++ b/plugins/thunar-sendto-email/main.c
@@ -76,8 +76,12 @@ struct _TseData
 
 /* well known archive types */
 static const char *TSE_MIME_TYPES[] = {
+  "application/x-7z-compressed",
+  "application/x-7z-compressed-tar",
   "application/x-ar",
   "application/x-arj",
+  "application/x-brotli",
+  "application/x-brotli-compressed-tar",
   "application/x-bzip",
   "application/x-bzip-compressed-tar",
   "application/x-compress",
@@ -87,9 +91,13 @@ static const char *TSE_MIME_TYPES[] = {
   "application/x-gzip",
   "application/x-lha",
   "application/x-lhz",
+  "application/x-lzma",
+  "application/x-lzma-compressed-tar",
   "application/x-rar",
   "application/x-rar-compressed",
   "application/x-tar",
+  "application/x-xz",
+  "application/x-xz-compressed-tar",
   "application/x-zip",
   "application/x-zip-compressed",
   "application/zip",
@@ -100,6 +108,8 @@ static const char *TSE_MIME_TYPES[] = {
   "application/x-lzop",
   "application/x-zoo",
   "application/x-cd-image",
+  "application/zstd",
+  "application/x-zstd-compressed-tar",
 };
 
 
@@ -139,12 +149,36 @@ tse_error (GError      *error,
   g_free (primary_text);
 }
 
+/**
+ * Check if the single file is already an archive
+ **/
+static gboolean
+tse_file_is_archive (GFileInfo *file_info)
+{
+  const gchar *content_type;
+  guint        n;
+  /* determine the content type */
+  content_type = g_file_info_get_content_type (file_info);
+  if (content_type == NULL)
+  {
+    return FALSE;
+  }
+  for (n = 0; n < G_N_ELEMENTS (TSE_MIME_TYPES); ++n)
+  {
+    /* check if this mime type matches */
+    if (g_content_type_is_a (content_type, TSE_MIME_TYPES[n]))
+    {
+      /* yep, that's a match then */
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
 
 
 static gint
 tse_ask_compress (GList *infos)
 {
-  const gchar *content_type;
   TseData     *tse_data;
   GtkWidget   *message;
   guint64      total_size = 0;
@@ -152,7 +186,6 @@ tse_ask_compress (GList *infos)
   gint         response = TSE_RESPONSE_PLAIN;
   gint         n_archives = 0;
   gint         n_infos = 0;
-  guint        n;
 
   /* check the file infos */
   for (lp = infos; lp != NULL; lp = lp->next, ++n_infos)
@@ -163,27 +196,15 @@ tse_ask_compress (GList *infos)
       if (g_file_info_get_file_type (tse_data->info) == G_FILE_TYPE_DIRECTORY)
         return TSE_RESPONSE_COMPRESS;
 
-      /* check if the single file is already an archive */
-      for (n = 0; n < G_N_ELEMENTS (TSE_MIME_TYPES); ++n)
-        {
-          /* determine the content type */
-          content_type = g_file_info_get_content_type (tse_data->info);
-
-          /* check if this mime type matches */
-          if (content_type != NULL && g_content_type_is_a (content_type, TSE_MIME_TYPES[n]))
-            {
-              /* yep, that's a match then */
-              ++n_archives;
-              break;
-            }
-        }
+      if (tse_file_is_archive (tse_data->info))
+        ++n_archives;
 
       /* add file size to total */
       total_size += g_file_info_get_size (tse_data->info);
     }
 
   /* check if the total size is larger than 200KiB, or we have more than
-   * one file, and atleast one of the files is not already an archive.
+   * one file, and at least one of the files is not already an archive.
    */
   if ((n_infos > 1 || total_size > 200 * 1024) && n_infos != n_archives)
     {
@@ -307,7 +328,7 @@ tse_progress (const gchar *working_directory,
   watch_id = g_child_watch_add (pid, tse_child_watch, dialog);
 
   /* start the pulse timer */
-  pulse_timer_id = g_timeout_add (125, (GSourceFunc) gtk_progress_bar_pulse, progress);
+  pulse_timer_id = g_timeout_add (125, (GSourceFunc) (void (*)(void)) gtk_progress_bar_pulse, progress);
 
   /* run the dialog */
   response = gtk_dialog_run (GTK_DIALOG (dialog));
@@ -597,7 +618,8 @@ main (int argc, char **argv)
       info = g_file_query_info (file,
                                 G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
                                 G_FILE_ATTRIBUTE_STANDARD_SIZE ","
-                                G_FILE_ATTRIBUTE_STANDARD_TYPE,
+                                G_FILE_ATTRIBUTE_STANDARD_TYPE ","
+                                G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
                                 G_FILE_QUERY_INFO_NONE, NULL, &error);
 
       /* check if we failed */
diff --git a/plugins/thunar-sendto-email/thunar-sendto-email.desktop.in.in b/plugins/thunar-sendto-email/thunar-sendto-email.desktop.in.in
index 539c7850..90e860f8 100644
--- a/plugins/thunar-sendto-email/thunar-sendto-email.desktop.in.in
+++ b/plugins/thunar-sendto-email/thunar-sendto-email.desktop.in.in
@@ -2,5 +2,5 @@
 Type=Application
 Version=1.0
 _Name=Mail Recipient
-Icon=internet-mail
+Icon=mail-send
 Exec=@HELPERDIR@/Thunar/thunar-sendto-email %F
diff --git a/plugins/thunar-tpa/thunar-tpa.c b/plugins/thunar-tpa/thunar-tpa.c
index 73a53eb2..baff39ab 100644
--- a/plugins/thunar-tpa/thunar-tpa.c
+++ b/plugins/thunar-tpa/thunar-tpa.c
@@ -156,7 +156,7 @@ thunar_tpa_init (ThunarTpa *plugin)
   GError *error = NULL;
 
   /* setup the button for the trash plugin */
-  plugin->button = xfce_create_panel_button ();
+  plugin->button = xfce_panel_create_button ();
   xfce_panel_plugin_add_action_widget (XFCE_PANEL_PLUGIN (plugin), plugin->button);
   gtk_drag_dest_set (plugin->button, GTK_DEST_DEFAULT_ALL, drop_targets, G_N_ELEMENTS (drop_targets), GDK_ACTION_MOVE);
   g_signal_connect_swapped (G_OBJECT (plugin->button), "clicked", G_CALLBACK (thunar_tpa_display_trash), plugin);
diff --git a/plugins/thunar-uca/thunar-uca-editor.c b/plugins/thunar-uca/thunar-uca-editor.c
index 58ac524e..9bc80754 100644
--- a/plugins/thunar-uca/thunar-uca-editor.c
+++ b/plugins/thunar-uca/thunar-uca-editor.c
@@ -655,7 +655,7 @@ thunar_uca_editor_save (ThunarUcaEditor *uca_editor,
                       -1);
 
   /* always clear the accelerator, it'll be updated in thunar_uca_model_update */
-  if (gtk_accel_map_lookup_entry (uca_editor->accel_path, &key) && key.accel_key != 0)
+  if (uca_editor->accel_path != NULL && gtk_accel_map_lookup_entry (uca_editor->accel_path, &key) && key.accel_key != 0)
     gtk_accel_map_change_entry (uca_editor->accel_path, 0, 0, TRUE);
 
   thunar_uca_model_update (uca_model, iter,
diff --git a/plugins/thunar-uca/thunar-uca-model.c b/plugins/thunar-uca/thunar-uca-model.c
index edee3e40..54f0dd12 100644
--- a/plugins/thunar-uca/thunar-uca-model.c
+++ b/plugins/thunar-uca/thunar-uca-model.c
@@ -1263,10 +1263,24 @@ thunar_uca_model_remove (ThunarUcaModel *uca_model,
 {
   ThunarUcaModelItem *item;
   GtkTreePath        *path;
+  gchar              *unique_id;
+  gchar              *accel_path;
+  GtkAccelKey         key;
 
   g_return_if_fail (THUNAR_UCA_IS_MODEL (uca_model));
   g_return_if_fail (iter->stamp == uca_model->stamp);
 
+  /* clear any accelerator associated to the item */
+  gtk_tree_model_get (GTK_TREE_MODEL (uca_model), iter,
+                      THUNAR_UCA_MODEL_COLUMN_UNIQUE_ID, &unique_id, 
+                      -1);
+  accel_path = g_strdup_printf ("<Actions>/ThunarActions/uca-action-%s", unique_id);
+
+  if (gtk_accel_map_lookup_entry (accel_path, &key) && key.accel_key != 0)
+    gtk_accel_map_change_entry (accel_path, 0, 0, TRUE);
+
+  g_free (accel_path);
+
   /* determine the path for the item to remove */
   path = gtk_tree_model_get_path (GTK_TREE_MODEL (uca_model), iter);
 
@@ -1426,7 +1440,7 @@ thunar_uca_model_save (ThunarUcaModel *uca_model,
   fp = fdopen (fd, "w");
 
   /* write the header */
-  fprintf (fp, "<?xml encoding=\"UTF-8\" version=\"1.0\"?>\n<actions>\n");
+  fprintf (fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<actions>\n");
 
   /* write the model items */
   for (lp = uca_model->items; lp != NULL; lp = lp->next)
diff --git a/plugins/thunar-uca/thunar-uca-provider.c b/plugins/thunar-uca/thunar-uca-provider.c
index 53dbc8d1..450616ce 100644
--- a/plugins/thunar-uca/thunar-uca-provider.c
+++ b/plugins/thunar-uca/thunar-uca-provider.c
@@ -246,7 +246,8 @@ thunar_uca_provider_get_file_menu_items (ThunarxMenuProvider *menu_provider,
 
           /* connect the "activate" signal */
           g_signal_connect_data (G_OBJECT (item), "activate", G_CALLBACK (thunar_uca_provider_activated),
-                                 g_object_ref (G_OBJECT (uca_provider)), (GClosureNotify) g_object_unref,
+                                 g_object_ref (G_OBJECT (uca_provider)),
+                                 (GClosureNotify) (void (*)(void)) g_object_unref,
                                  G_CONNECT_SWAPPED);
 
           /* set the action path */
diff --git a/plugins/thunar-wallpaper/twp-provider.c b/plugins/thunar-wallpaper/twp-provider.c
index 92d09cd2..887ae646 100644
--- a/plugins/thunar-wallpaper/twp-provider.c
+++ b/plugins/thunar-wallpaper/twp-provider.c
@@ -50,22 +50,9 @@ static void   twp_action_set_wallpaper          (ThunarxMenuItem          *item,
                                                  gpointer                  user_data);
 static gint   twp_get_active_workspace_number   (GdkScreen *screen);
 
-
-typedef enum
-{
-  DESKTOP_TYPE_NONE,
-  DESKTOP_TYPE_XFCE,
-  DESKTOP_TYPE_NAUTILUS
-} DesktopType;
-
-
-
-static DesktopType desktop_type = DESKTOP_TYPE_NONE;
-static gboolean    _has_gconftool = FALSE;
+static gboolean    _has_gsettings = FALSE;
 static GtkWidget   *main_window = NULL;
 
-
-
 struct _TwpProviderClass
 {
   GObjectClass __parent__;
@@ -107,10 +94,10 @@ twp_provider_init (TwpProvider *twp_provider)
 {
   gchar *program;
 
-  program = g_find_program_in_path ("gconftool-2");
+  program = g_find_program_in_path ("gsettings");
   if (G_LIKELY (program != NULL))
     {
-      _has_gconftool = TRUE;
+      _has_gsettings = TRUE;
       g_free (program);
     }
 }
@@ -134,19 +121,8 @@ twp_provider_get_file_menu_items (ThunarxMenuProvider *menu_provider,
   GFile           *location;
   GList           *items = NULL;
   gchar           *mime_type;
-  gchar            selection_name[100];
-  Atom             xfce_selection_atom;
-  Atom             nautilus_selection_atom;
-  GdkScreen       *gdk_screen = gdk_screen_get_default();
-  gint             xscreen = gdk_x11_screen_get_screen_number(gdk_screen);
-
-  if(g_strcmp0 (g_getenv ("XDG_SESSION_TYPE"), "wayland") == 0)
-    {
-      return items; // wayland crashes on "gdk_x11_get_default_xdisplay"
-    }
 
   main_window = window;
-  desktop_type = DESKTOP_TYPE_NONE;
 
   /* we can only set a single wallpaper */
   if (files->next == NULL)
@@ -184,25 +160,6 @@ twp_provider_get_file_menu_items (ThunarxMenuProvider *menu_provider,
         }
     }
 
-  g_snprintf(selection_name, 100, XFDESKTOP_SELECTION_FMT, xscreen);
-  xfce_selection_atom = XInternAtom (gdk_x11_get_default_xdisplay(), selection_name, False);
-
-  if ((XGetSelectionOwner(gdk_x11_get_default_xdisplay(), xfce_selection_atom)))
-    {
-        desktop_type = DESKTOP_TYPE_XFCE;
-    }
-  else
-    {
-      /* FIXME: This is wrong, nautilus WINDOW_ID is not a selection */
-      g_snprintf(selection_name, 100, NAUTILUS_SELECTION_FMT);
-      nautilus_selection_atom = XInternAtom (gdk_x11_get_default_xdisplay(), selection_name, False);
-      if((XGetSelectionOwner(gdk_x11_get_default_xdisplay(), nautilus_selection_atom)))
-      {
-          if (_has_gconftool)
-              desktop_type = DESKTOP_TYPE_NAUTILUS;
-      }
-    }
-
   return items;
 }
 
@@ -230,23 +187,26 @@ twp_action_set_wallpaper (ThunarxMenuItem *item,
   XfconfChannel   *channel;
   gboolean         is_single_workspace;
   gint             current_image_style;
+  const gchar     *desktop_type = NULL;
 
   screen = gdk_display_get_default_screen (display);
 
-  if (desktop_type != DESKTOP_TYPE_NONE)
+  desktop_type = g_getenv ("XDG_CURRENT_DESKTOP");
+  if (desktop_type == NULL)
     {
-      file_uri = thunarx_file_info_get_uri (file_info);
-      file_name = g_filename_from_uri (file_uri, &hostname, NULL);
-      if (hostname != NULL)
-        {
-          g_free (hostname);
-          g_free (file_uri);
-          g_free (file_name);
-
-          return;
-        }
+      g_warning ("Failed to set wallpaper: $XDG_CURRENT_DESKTOP is not defined");
+      return;
+    }
 
+  file_uri = thunarx_file_info_get_uri (file_info);
+  file_name = g_filename_from_uri (file_uri, &hostname, NULL);
+  if (hostname != NULL)
+    {
+      g_free (hostname);
       g_free (file_uri);
+      g_free (file_name);
+
+      return;
     }
 
   workspace = twp_get_active_workspace_number (screen);
@@ -264,105 +224,103 @@ twp_action_set_wallpaper (ThunarxMenuItem *item,
   monitor_name = gdk_monitor_get_model (monitor);
   escaped_file_name = g_shell_quote (file_name);
 
-  switch (desktop_type)
+  if (g_strcmp0 (desktop_type, "XFCE") == 0)
+    {
+      g_debug ("set on xfce");
+
+      channel = xfconf_channel_get ("xfce4-desktop");
+
+      /* This is the format for xfdesktop before 4.11 */
+      image_path_prop = g_strdup_printf("/backdrop/screen%d/monitor%d/image-path", screen_nr, monitor_nr);
+      image_show_prop = g_strdup_printf("/backdrop/screen%d/monitor%d/image-show", screen_nr, monitor_nr);
+      image_style_prop = g_strdup_printf("/backdrop/screen%d/monitor%d/image-style", screen_nr, monitor_nr);
+
+      /* Set the wallpaper and ensure that it's set to show */
+      xfconf_channel_set_string (channel, image_path_prop, file_name);
+      xfconf_channel_set_bool (channel, image_show_prop, TRUE);
+
+      /* If there isn't a wallpaper style set, then set one */
+      current_image_style = xfconf_channel_get_int (channel, image_style_prop, -1);
+      if (current_image_style == -1)
+        {
+          xfconf_channel_set_int (channel, image_style_prop, 0);
+        }
+
+      g_free(image_path_prop);
+      g_free(image_show_prop);
+      g_free(image_style_prop);
+
+
+      /* Xfdesktop 4.11+ has a concept of a single-workspace-mode where
+       * the same workspace is used for everything but additionally allows
+       * the user to use any current workspace as the single active
+       * workspace, we'll need to check if it is enabled (which by default
+       * it is) and use that. */
+      is_single_workspace = xfconf_channel_get_bool (channel, "/backdrop/single-workspace-mode", TRUE);
+      if (is_single_workspace)
+        {
+          workspace = xfconf_channel_get_int (channel, "/backdrop/single-workspace-number", 0);
+        }
+
+      /* This is the format for xfdesktop post 4.11. A workspace number is
+       * added and the monitor is referred to name. We set both formats so
+       * that it works as the user expects. */
+      if (monitor_name)
+        {
+          image_path_prop = g_strdup_printf("/backdrop/screen%d/monitor%s/workspace%d/last-image", screen_nr, monitor_name, workspace);
+          image_style_prop = g_strdup_printf("/backdrop/screen%d/monitor%s/workspace%d/image-style", screen_nr, monitor_name, workspace);
+        }
+      else
+        {
+          /* gdk_screen_get_monitor_plug_name can return NULL, in those
+           * instances we fallback to monitor number but still include the
+           * workspace number */
+          image_path_prop = g_strdup_printf("/backdrop/screen%d/monitor%d/workspace%d/last-image", screen_nr, monitor_nr, workspace);
+          image_style_prop = g_strdup_printf("/backdrop/screen%d/monitor%d/workspace%d/image-style", screen_nr, monitor_nr, workspace);
+        }
+
+      xfconf_channel_set_string (channel, image_path_prop, file_name);
+
+      /* If there isn't a wallpaper style set, then set one */
+      current_image_style = xfconf_channel_get_int (channel, image_style_prop, -1);
+      if (current_image_style == -1)
+        {
+          xfconf_channel_set_int (channel, image_style_prop, 5);
+        }
+
+      g_free(image_path_prop);
+      g_free(image_style_prop);
+    }
+  else if (g_strcmp0 (desktop_type, "GNOME") == 0)
+    {
+      if (_has_gsettings)
+        {
+          g_debug ("set on gnome");
+
+          command = g_strdup_printf ("gsettings set "
+                                     "org.gnome.desktop.background picture-uri "
+                                     "'%s'", file_uri);
+          g_spawn_command_line_async (command, NULL);
+          g_free (command);
+        }
+      else
+        {
+          g_warning ("Failed to set wallpaper: Missing executable 'gsettings'");
+        }
+    }
+  else
     {
-      case DESKTOP_TYPE_XFCE:
-        g_debug ("set on xfce");
-
-        channel = xfconf_channel_get ("xfce4-desktop");
-
-        /* This is the format for xfdesktop before 4.11 */
-        image_path_prop = g_strdup_printf("/backdrop/screen%d/monitor%d/image-path", screen_nr, monitor_nr);
-        image_show_prop = g_strdup_printf("/backdrop/screen%d/monitor%d/image-show", screen_nr, monitor_nr);
-        image_style_prop = g_strdup_printf("/backdrop/screen%d/monitor%d/image-style", screen_nr, monitor_nr);
-
-        /* Set the wallpaper and ensure that it's set to show */
-        xfconf_channel_set_string (channel, image_path_prop, file_name);
-        xfconf_channel_set_bool (channel, image_show_prop, TRUE);
-
-        /* If there isn't a wallpaper style set, then set one */
-        current_image_style = xfconf_channel_get_int (channel, image_style_prop, -1);
-        if (current_image_style == -1)
-          {
-            xfconf_channel_set_int (channel, image_style_prop, 0);
-          }
-
-        g_free(image_path_prop);
-        g_free(image_show_prop);
-        g_free(image_style_prop);
-
-
-        /* Xfdesktop 4.11+ has a concept of a single-workspace-mode where
-         * the same workspace is used for everything but additionally allows
-         * the user to use any current workspace as the single active
-         * workspace, we'll need to check if it is enabled (which by default
-         * it is) and use that. */
-        is_single_workspace = xfconf_channel_get_bool (channel, "/backdrop/single-workspace-mode", TRUE);
-        if (is_single_workspace)
-          {
-            workspace = xfconf_channel_get_int (channel, "/backdrop/single-workspace-number", 0);
-          }
-
-        /* This is the format for xfdesktop post 4.11. A workspace number is
-         * added and the monitor is referred to name. We set both formats so
-         * that it works as the user expects. */
-        if (monitor_name)
-          {
-            image_path_prop = g_strdup_printf("/backdrop/screen%d/monitor%s/workspace%d/last-image", screen_nr, monitor_name, workspace);
-            image_style_prop = g_strdup_printf("/backdrop/screen%d/monitor%s/workspace%d/image-style", screen_nr, monitor_name, workspace);
-          }
-        else
-          {
-            /* gdk_screen_get_monitor_plug_name can return NULL, in those
-             * instances we fallback to monitor number but still include the
-             * workspace number */
-            image_path_prop = g_strdup_printf("/backdrop/screen%d/monitor%d/workspace%d/last-image", screen_nr, monitor_nr, workspace);
-            image_style_prop = g_strdup_printf("/backdrop/screen%d/monitor%d/workspace%d/image-style", screen_nr, monitor_nr, workspace);
-          }
-
-        xfconf_channel_set_string (channel, image_path_prop, file_name);
-
-        /* If there isn't a wallpaper style set, then set one */
-        current_image_style = xfconf_channel_get_int (channel, image_style_prop, -1);
-        if (current_image_style == -1)
-          {
-            xfconf_channel_set_int (channel, image_style_prop, 5);
-          }
-
-        g_free(image_path_prop);
-        g_free(image_style_prop);
-        break;
-
-      case DESKTOP_TYPE_NAUTILUS:
-        g_debug ("set on gnome");
-        image_path_prop = g_strdup_printf("/desktop/gnome/background/picture_filename");
-        image_show_prop = g_strdup_printf("/desktop/gnome/background/draw_background");
-
-        command = g_strdup_printf ("gconftool-2 %s --set %s--type string", image_path_prop, escaped_file_name);
-        g_spawn_command_line_async (command, NULL);
-        g_free (command);
-
-
-        command = g_strdup_printf ("gconftool-2 %s --set true --type boolean", image_show_prop);
-        g_spawn_command_line_async (command, NULL);
-        g_free (command);
-
-        g_free(image_path_prop);
-        g_free(image_show_prop);
-        break;
-
-      default:
-        return;
-        break;
+      g_warning (("Failed to set wallpaper: $XDG_CURRENT_DESKTOP Desktop type '%s' not supported by thunar wallpaper plugin."), desktop_type);
     }
 
   g_free (escaped_file_name);
   g_free (file_name);
+  g_free (file_uri);
 }
 
 /* Taken from xfce_spawn_get_active_workspace_number in xfce-spawn.c apart of
  * the libxfce4ui library.
- * http://git.xfce.org/xfce/libxfce4ui/tree/libxfce4ui/xfce-spawn.c#n193
+ * https://git.xfce.org/xfce/libxfce4ui/tree/libxfce4ui/xfce-spawn.c#n193
  */
 static gint
 twp_get_active_workspace_number (GdkScreen *screen)
diff --git a/po/hy.po b/po/hy.po
new file mode 100644
index 00000000..86bb804d
diff --git a/po/hy_AM.po b/po/hy_AM.po
new file mode 100644
index 00000000..9d9d45d3
diff --git a/po/hye.po b/po/hye.po
new file mode 100644
index 00000000..1227a856
diff --git a/po/ie.po b/po/ie.po
new file mode 100644
index 00000000..381703d8
diff --git a/Thunar-bulk-rename.desktop.in.in b/thunar-bulk-rename.desktop.in.in
similarity index 100%
rename from Thunar-bulk-rename.desktop.in.in
rename to thunar-bulk-rename.desktop.in.in
diff --git a/Thunar.desktop.in.in b/thunar.desktop.in.in
diff --git a/Thunar.desktop.in.in b/thunar.desktop.in.in
similarity index 91%
rename from Thunar.desktop.in.in
rename to thunar.desktop.in.in
index 739ea437..734b1b89 100644
--- a/Thunar.desktop.in.in
+++ b/thunar.desktop.in.in
@@ -8,5 +8,6 @@ Terminal=false
 StartupNotify=true
 Type=Application
 Categories=System;Utility;Core;GTK;FileTools;FileManager;
+MimeType=inode/directory;
 
 # vi:set encoding=UTF-8:
diff --git a/thunar/Makefile.am b/thunar/Makefile.am
index a92ae747..cff7b495 100644
--- a/thunar/Makefile.am
+++ b/thunar/Makefile.am
@@ -144,8 +144,6 @@ thunar_SOURCES =							\
 	thunar-location-entry.h						\
 	thunar-menu-util.c						\
 	thunar-menu-util.h						\
-	thunar-misc-jobs.c						\
-	thunar-misc-jobs.h						\
 	thunar-notify.c							\
 	thunar-notify.h							\
 	thunar-navigator.c						\
@@ -231,6 +229,7 @@ thunar_CFLAGS =								\
 	$(LIBSM_CFLAGS)							\
 	$(LIBXFCE4UI_CFLAGS)						\
 	$(XFCONF_CFLAGS)						\
+	$(PANGO_CFLAGS)							\
 	$(PLATFORM_CFLAGS)
 
 thunar_LDFLAGS =							\
@@ -247,7 +246,8 @@ thunar_LDADD =								\
 	$(LIBNOTIFY_LIBS)						\
 	$(LIBSM_LIBS)							\
 	$(LIBXFCE4UI_LIBS)						\
-	$(XFCONF_LIBS)
+	$(XFCONF_LIBS)							\
+	$(PANGO_LIBS)
 
 thunar_DEPENDENCIES =							\
 	$(top_builddir)/thunarx/libthunarx-$(THUNARX_VERSION_API).la
diff --git a/thunar/thunar-abstract-icon-view.c b/thunar/thunar-abstract-icon-view.c
index f53f4530..91ee300a 100644
--- a/thunar/thunar-abstract-icon-view.c
+++ b/thunar/thunar-abstract-icon-view.c
@@ -32,10 +32,6 @@
 
 
 
-#define THUNAR_ABSTRACT_ICON_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNAR_TYPE_ABSTRACT_ICON_VIEW, ThunarAbstractIconViewPrivate))
-
-
-
 static void         thunar_abstract_icon_view_style_set             (GtkWidget                    *widget,
                                                                      GtkStyle                     *previous_style);
 static void         thunar_abstract_icon_view_connect_ui_manager    (ThunarStandardView           *standard_view,
@@ -133,7 +129,7 @@ static const GtkRadioActionEntry order_action_entries[] =
 
 
 
-G_DEFINE_ABSTRACT_TYPE (ThunarAbstractIconView, thunar_abstract_icon_view, THUNAR_TYPE_STANDARD_VIEW)
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ThunarAbstractIconView, thunar_abstract_icon_view, THUNAR_TYPE_STANDARD_VIEW)
 
 
 
@@ -143,9 +139,6 @@ thunar_abstract_icon_view_class_init (ThunarAbstractIconViewClass *klass)
   ThunarStandardViewClass *thunarstandard_view_class;
   GtkWidgetClass          *gtkwidget_class;
 
-  /* add private data to the instance type */
-  g_type_class_add_private (klass, sizeof (ThunarAbstractIconViewPrivate));
-
   gtkwidget_class = GTK_WIDGET_CLASS (klass);
   gtkwidget_class->style_set = thunar_abstract_icon_view_style_set;
 
@@ -198,7 +191,7 @@ thunar_abstract_icon_view_init (ThunarAbstractIconView *abstract_icon_view)
   GtkWidget *view;
 
   /* connect private instance data */
-  abstract_icon_view->priv = THUNAR_ABSTRACT_ICON_VIEW_GET_PRIVATE (abstract_icon_view);
+  abstract_icon_view->priv = thunar_abstract_icon_view_get_instance_private (abstract_icon_view);
 
   /* stay informed about zoom-level changes, so we can force a re-layout on the abstract_icon view */
   g_signal_connect (G_OBJECT (abstract_icon_view), "notify::zoom-level", G_CALLBACK (thunar_abstract_icon_view_zoom_level_changed), NULL);
diff --git a/thunar/thunar-application.c b/thunar/thunar-application.c
index 694db532..c0ca694d 100644
--- a/thunar/thunar-application.c
+++ b/thunar/thunar-application.c
@@ -117,10 +117,7 @@ static void           thunar_application_dbus_acquired_cb       (GDBusConnection
 static void           thunar_application_name_acquired_cb       (GDBusConnection        *connection,
                                                                  const gchar            *name,
                                                                  gpointer                user_data);
-static void           thunar_application_dbus_name_lost_crit_cb (GDBusConnection        *connection,
-                                                                 const gchar            *name,
-                                                                 gpointer                user_data);
-static void           thunar_application_dbus_name_lost_warn_cb (GDBusConnection        *connection,
+static void           thunar_application_dbus_name_lost_cb      (GDBusConnection        *connection,
                                                                  const gchar            *name,
                                                                  gpointer                user_data);
 static void           thunar_application_dbus_init              (ThunarApplication      *application);
@@ -182,37 +179,38 @@ struct _ThunarApplicationClass
 
 struct _ThunarApplication
 {
-  GtkApplication         __parent__;
+  GtkApplication                 __parent__;
 
-  ThunarSessionClient   *session_client;
+  ThunarSessionClient            *session_client;
 
-  ThunarPreferences     *preferences;
-  GtkWidget             *progress_dialog;
+  ThunarPreferences              *preferences;
+  GtkWidget                      *progress_dialog;
 
-  ThunarThumbnailCache  *thumbnail_cache;
-  ThunarThumbnailer     *thumbnailer;
+  ThunarThumbnailCache           *thumbnail_cache;
+  ThunarThumbnailer              *thumbnailer;
 
-  ThunarDBusService     *dbus_service;
+  ThunarDBusService              *dbus_service;
 
-  gboolean               daemon;
+  gboolean                        daemon;
 
-  guint                  accel_map_save_id;
-  GtkAccelMap           *accel_map;
+  guint                           accel_map_save_id;
+  GtkAccelMap                    *accel_map;
 
-  guint                  show_dialogs_timer_id;
+  guint                           show_dialogs_timer_id;
 
 #ifdef HAVE_GUDEV
-  GUdevClient           *udev_client;
+  GUdevClient                    *udev_client;
 
-  GSList                *volman_udis;
-  guint                  volman_idle_id;
-  guint                  volman_watch_id;
+  GSList                         *volman_udis;
+  guint                           volman_idle_id;
+  guint                           volman_watch_id;
 #endif
 
-  GList                 *files_to_launch;
+  GList                          *files_to_launch;
+  ThunarApplicationProcessAction  process_file_action;
 
-  guint                  dbus_owner_id_xfce;
-  guint                  dbus_owner_id_fdo;
+  guint                           dbus_owner_id_xfce;
+  guint                           dbus_owner_id_fdo;
 };
 
 
@@ -279,6 +277,7 @@ thunar_application_init (ThunarApplication *application)
    * in the primary instance anyways */
 
   application->files_to_launch = NULL;
+  application->process_file_action = THUNAR_APPLICATION_SELECT_FILES;
   application->progress_dialog = NULL;
   application->preferences     = NULL;
 
@@ -308,19 +307,7 @@ thunar_application_name_acquired_cb (GDBusConnection *connection,
 
 
 static void
-thunar_application_dbus_name_lost_crit_cb (GDBusConnection *connection,
-                                      const gchar     *name,
-                                      gpointer         user_data)
-{
-  ThunarApplication *application = user_data;
-  g_critical (_("Name '%s' lost on the message dbus, exiting."), name);
-  g_application_quit (G_APPLICATION (application));
-}
-
-
-
-static void
-thunar_application_dbus_name_lost_warn_cb (GDBusConnection *connection,
+thunar_application_dbus_name_lost_cb (GDBusConnection *connection,
                                       const gchar     *name,
                                       gpointer         user_data)
 {
@@ -330,20 +317,16 @@ thunar_application_dbus_name_lost_warn_cb (GDBusConnection *connection,
 
 
 /* TODO: [GTK3 Port] Check if there's a cleaner way to register */
-/* this extra dbus name (besides org.xfce.Thunar) */
+/* these extra dbus names (besides org.xfce.Thunar) */
 static void
 thunar_application_dbus_init (ThunarApplication *application)
 {
-    /* Do not atempt to register if running as root */
-    if (geteuid() == 0)
-      return;
-
     application->dbus_owner_id_xfce = g_bus_own_name (G_BUS_TYPE_SESSION,
                                       "org.xfce.FileManager",
                                       G_BUS_NAME_OWNER_FLAGS_NONE,
                                       thunar_application_dbus_acquired_cb,
                                       thunar_application_name_acquired_cb,
-                                      thunar_application_dbus_name_lost_crit_cb,
+                                      thunar_application_dbus_name_lost_cb,
                                       application,
                                       NULL);
 
@@ -352,7 +335,7 @@ thunar_application_dbus_init (ThunarApplication *application)
                                      G_BUS_NAME_OWNER_FLAGS_NONE,
                                      thunar_application_dbus_acquired_cb,
                                      thunar_application_name_acquired_cb,
-                                     thunar_application_dbus_name_lost_warn_cb,
+                                     thunar_application_dbus_name_lost_cb,
                                      application,
                                      NULL);
 }
@@ -488,7 +471,7 @@ thunar_application_handle_local_options (GApplication *gapp,
   if (G_UNLIKELY (opt_version))
     {
       g_print ("%s %s (Xfce %s)\n\n", PACKAGE_NAME, PACKAGE_VERSION, xfce_version_string ());
-      g_print ("%s\n", "Copyright (c) 2004-2015");
+      g_print ("%s\n", "Copyright (c) 2004-2019");
       g_print ("\t%s\n\n", _("The Thunar development team. All rights reserved."));
       g_print ("%s\n\n", _("Written by Benedikt Meurer <benny@xfce.org>."));
       g_print (_("Please report bugs to <%s>."), PACKAGE_BUGREPORT);
@@ -548,7 +531,7 @@ thunar_application_command_line (GApplication            *gapp,
     }
   else if (filenames != NULL)
     {
-      if (!thunar_application_process_filenames (application, cwd, filenames, NULL, NULL, &error))
+      if (!thunar_application_process_filenames (application, cwd, filenames, NULL, NULL, &error, THUNAR_APPLICATION_SELECT_FILES))
         {
           /* we failed to process the filenames or the bulk rename failed */
           g_application_command_line_printerr (command_line, "Thunar: %s\n", error->message);
@@ -556,7 +539,7 @@ thunar_application_command_line (GApplication            *gapp,
     }
   else if (!daemon)
     {
-      if (!thunar_application_process_filenames (application, cwd, cwd_list, NULL, NULL, &error))
+      if (!thunar_application_process_filenames (application, cwd, cwd_list, NULL, NULL, &error, THUNAR_APPLICATION_SELECT_FILES))
         {
           /* we failed to process the filenames or the bulk rename failed */
           g_application_command_line_printerr (command_line, "Thunar: %s\n", error->message);
@@ -612,7 +595,7 @@ thunar_application_load_css (void)
     /* add missing top border to side pane */
     ".shortcuts-pane { border-top-style: solid; }"
     /* make border thicker during DnD */
-    ".standard-view { border-left-width: 0px; }"
+    ".standard-view { border-left-width: 0px; border-right-width: 0px; }"
     ".standard-view:drop(active) { border-width: 2px; }", -1, NULL);
   screen = gdk_screen_get_default ();
   gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (css_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
@@ -927,7 +910,7 @@ thunar_application_uevent (GUdevClient       *client,
     {
       /* only insert the path if we don't have it already */
       if (g_slist_find_custom (application->volman_udis, sysfs_path,
-                               (GCompareFunc) g_utf8_collate) == NULL)
+                               (GCompareFunc) (void (*)(void)) g_utf8_collate) == NULL)
         {
           application->volman_udis = g_slist_prepend (application->volman_udis,
                                                       g_strdup (sysfs_path));
@@ -947,7 +930,7 @@ thunar_application_uevent (GUdevClient       *client,
     {
       /* look for the sysfs path in the list of pending paths */
       lp = g_slist_find_custom (application->volman_udis, sysfs_path,
-                                (GCompareFunc) g_utf8_collate);
+                                (GCompareFunc) (void (*)(void)) g_utf8_collate);
 
       if (G_LIKELY (lp != NULL))
         {
@@ -1276,7 +1259,7 @@ thunar_application_take_window (ThunarApplication *application,
     {
       group = gtk_window_group_new ();
       gtk_window_group_add_window (group, window);
-      g_object_weak_ref (G_OBJECT (window), (GWeakNotify) g_object_unref, group);
+      g_object_weak_ref (G_OBJECT (window), (GWeakNotify) (void (*)(void)) g_object_unref, group);
     }
 
   /* add the ourselves to the window */
@@ -1526,8 +1509,27 @@ thunar_application_process_files_finish (ThunarBrowser *browser,
     }
   else
     {
-      /* try to open the file or directory */
-      thunar_file_launch (target_file, screen, startup_id, &error);
+      if (application->process_file_action == THUNAR_APPLICATION_LAUNCH_FILES)
+        {
+          /* try to launch the file / open the directory */
+          thunar_file_launch (target_file, screen, startup_id, &error);
+        }
+      else if (thunar_file_is_directory (file))
+        {
+          thunar_application_open_window (application, file, screen, startup_id, FALSE);
+        }
+      else
+        {
+          /* Note that for security reasons we do not execute files passed via command line */
+          /* Lets rather open the containing directory */
+          ThunarFile *parent = thunar_file_get_parent (file, NULL);
+
+          if (G_LIKELY (parent != NULL))
+            {
+              thunar_application_open_window (application, parent, screen, startup_id, FALSE);
+              g_object_unref (parent);
+            }
+        }
 
       /* remove the file from the list */
       application->files_to_launch = g_list_delete_link (application->files_to_launch,
@@ -1596,18 +1598,20 @@ thunar_application_process_files (ThunarApplication *application)
  * @startup_id        : startup id to finish startup notification and properly focus the
  *                      window when focus stealing is enabled or %NULL.
  * @error             : return location for errors or %NULL.
+ * @action            : action to invoke on the files
  *
  * Tells @application to process the given @filenames and launch them appropriately.
  *
  * Return value: %TRUE on success, %FALSE if @error is set.
  **/
 gboolean
-thunar_application_process_filenames (ThunarApplication *application,
-                                      const gchar       *working_directory,
-                                      gchar            **filenames,
-                                      GdkScreen         *screen,
-                                      const gchar       *startup_id,
-                                      GError           **error)
+thunar_application_process_filenames (ThunarApplication               *application,
+                                      const gchar                     *working_directory,
+                                      gchar                          **filenames,
+                                      GdkScreen                       *screen,
+                                      const gchar                     *startup_id,
+                                      GError                         **error,
+                                      ThunarApplicationProcessAction   action)
 {
   ThunarFile *file;
   GError     *derror = NULL;
@@ -1679,7 +1683,10 @@ thunar_application_process_filenames (ThunarApplication *application,
 
   /* start processing files if we have any to launch */
   if (application->files_to_launch != NULL)
-    thunar_application_process_files (application);
+    {
+      application->process_file_action = action;
+      thunar_application_process_files (application);
+    }
 
   /* free the file list */
   g_list_free (file_list);
diff --git a/thunar/thunar-application.h b/thunar/thunar-application.h
index 547cb701..8c180e8c 100644
--- a/thunar/thunar-application.h
+++ b/thunar/thunar-application.h
@@ -31,6 +31,12 @@ G_BEGIN_DECLS;
 typedef struct _ThunarApplicationClass ThunarApplicationClass;
 typedef struct _ThunarApplication      ThunarApplication;
 
+typedef enum
+{
+  THUNAR_APPLICATION_LAUNCH_FILES,
+  THUNAR_APPLICATION_SELECT_FILES
+} ThunarApplicationProcessAction;
+
 #define THUNAR_TYPE_APPLICATION             (thunar_application_get_type ())
 #define THUNAR_APPLICATION(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_APPLICATION, ThunarApplication))
 #define THUNAR_APPLICATION_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_APPLICATION, ThunarApplicationClass))
@@ -74,7 +80,8 @@ gboolean              thunar_application_process_filenames          (ThunarAppli
                                                                      gchar            **filenames,
                                                                      GdkScreen         *screen,
                                                                      const gchar       *startup_id,
-                                                                     GError           **error);
+                                                                     GError           **error,
+                                                                     ThunarApplicationProcessAction action);
 
 void                  thunar_application_rename_file                (ThunarApplication *application,
                                                                      ThunarFile        *file,
diff --git a/thunar/thunar-column-model.c b/thunar/thunar-column-model.c
index 35ac6fc2..1ece1be7 100644
--- a/thunar/thunar-column-model.c
+++ b/thunar/thunar-column-model.c
@@ -86,6 +86,7 @@ static void               thunar_column_model_save_visible_columns    (ThunarCol
 static void               thunar_column_model_notify_visible_columns  (ThunarPreferences      *preferences,
                                                                        GParamSpec             *pspec,
                                                                        ThunarColumnModel      *column_model);
+static gboolean           thunar_column_model_set_column_width_timer  (gpointer                user_data);
 
 
 
@@ -113,6 +114,7 @@ struct _ThunarColumnModel
   ThunarColumn       order[THUNAR_N_VISIBLE_COLUMNS];
   gboolean           visible[THUNAR_N_VISIBLE_COLUMNS];
   gint               width[THUNAR_N_VISIBLE_COLUMNS];
+  guint              save_width_timer_id;
 };
 
 
@@ -211,6 +213,10 @@ thunar_column_model_finalize (GObject *object)
   g_signal_handlers_disconnect_matched (G_OBJECT (column_model->preferences), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, column_model);
   g_object_unref (G_OBJECT (column_model->preferences));
 
+  /* drop any running "save width" timer */
+  if (G_UNLIKELY (column_model->save_width_timer_id != 0))
+    g_source_remove (column_model->save_width_timer_id);
+
   (*G_OBJECT_CLASS (thunar_column_model_parent_class)->finalize) (object);
 }
 
@@ -720,6 +726,19 @@ thunar_column_model_notify_visible_columns (ThunarPreferences *preferences,
 
 
 
+static gboolean
+thunar_column_model_set_column_width_timer (gpointer user_data)
+{
+  ThunarColumnModel *column_model = THUNAR_COLUMN_MODEL (user_data);
+
+  thunar_column_model_save_column_widths (column_model);
+  column_model->save_width_timer_id = 0;
+
+  return FALSE;
+}
+
+
+
 /**
  * thunar_column_model_get_default:
  *
@@ -998,8 +1017,14 @@ thunar_column_model_set_column_width (ThunarColumnModel *column_model,
       /* apply the new value */
       column_model->width[column] = width;
 
-      /* store the settings */
-      thunar_column_model_save_column_widths (column_model);
+      /* store the settings... */
+      if (column_model->save_width_timer_id != 0)
+        g_source_remove (column_model->save_width_timer_id);
+
+      /* ... asynchronously and only once to not overload xfconf */
+      column_model->save_width_timer_id = g_timeout_add (1000,
+                                                         thunar_column_model_set_column_width_timer,
+                                                         column_model);
     }
 }
 
diff --git a/thunar/thunar-component.c b/thunar/thunar-component.c
index ddd42435..29cd6849 100644
--- a/thunar/thunar-component.c
+++ b/thunar/thunar-component.c
@@ -43,7 +43,7 @@ thunar_component_get_type (void)
       type = g_type_register_static_simple (G_TYPE_INTERFACE,
                                             I_("ThunarComponent"),
                                             sizeof (ThunarComponentIface),
-                                            (GClassInitFunc) thunar_component_class_init,
+                                            (GClassInitFunc) (void (*)(void)) thunar_component_class_init,
                                             0,
                                             NULL,
                                             0);
diff --git a/thunar/thunar-create-dialog.c b/thunar/thunar-create-dialog.c
index 6fb204ba..b14d5bb0 100644
--- a/thunar/thunar-create-dialog.c
+++ b/thunar/thunar-create-dialog.c
@@ -156,7 +156,7 @@ thunar_create_dialog_init (ThunarCreateDialog *dialog)
   gtk_grid_attach (GTK_GRID (grid), dialog->image, 0, 0, 1, 2);
   gtk_widget_show (dialog->image);
 
-  label = g_object_new (GTK_TYPE_LABEL, "label", _("Enter the new name:"), "xalign", 0.0f, "hexpand", TRUE, NULL);
+  label = g_object_new (GTK_TYPE_LABEL, "label", _("Enter the name:"), "xalign", 0.0f, "hexpand", TRUE, NULL);
   gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
   gtk_widget_show (label);
 
diff --git a/thunar/thunar-dbus-service.c b/thunar/thunar-dbus-service.c
index 2d27642d..4205a2b2 100644
--- a/thunar/thunar-dbus-service.c
+++ b/thunar/thunar-dbus-service.c
@@ -991,7 +991,7 @@ thunar_dbus_service_launch_files (ThunarDBusFileManager  *object,
     {
       /* let the application process the filenames */
       application = thunar_application_get ();
-      thunar_application_process_filenames (application, working_directory, filenames, screen, startup_id, &error);
+      thunar_application_process_filenames (application, working_directory, filenames, screen, startup_id, &error, THUNAR_APPLICATION_LAUNCH_FILES);
       g_object_unref (G_OBJECT (application));
 
       /* release the screen */
diff --git a/thunar/thunar-deep-count-job.c b/thunar/thunar-deep-count-job.c
index d36572eb..7efc400a 100644
--- a/thunar/thunar-deep-count-job.c
+++ b/thunar/thunar-deep-count-job.c
@@ -409,7 +409,7 @@ thunar_deep_count_job_new (GList               *files,
   job->files = g_list_copy (files);
   job->query_flags = flags;
 
-  g_list_foreach (job->files, (GFunc) g_object_ref, NULL);
+  g_list_foreach (job->files, (GFunc) (void (*)(void)) g_object_ref, NULL);
 
   return job;
 }
diff --git a/thunar/thunar-details-view.c b/thunar/thunar-details-view.c
index 5dabad6e..c0f585ee 100644
--- a/thunar/thunar-details-view.c
+++ b/thunar/thunar-details-view.c
@@ -269,7 +269,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
 
           /* add the name renderer */
           g_object_set (G_OBJECT (THUNAR_STANDARD_VIEW (details_view)->name_renderer),
-                        "xalign", 0.0, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+                        "xalign", 0.0, "ellipsize", PANGO_ELLIPSIZE_END, "width-chars", 30, NULL);
           gtk_tree_view_column_pack_start (details_view->columns[column], THUNAR_STANDARD_VIEW (details_view)->name_renderer, TRUE);
           gtk_tree_view_column_set_attributes (details_view->columns[column], THUNAR_STANDARD_VIEW (details_view)->name_renderer,
                                                "text", THUNAR_COLUMN_NAME,
@@ -690,6 +690,9 @@ thunar_details_view_button_press_event (GtkTreeView       *tree_view,
       && !gtk_tree_view_get_path_at_pos (tree_view, event->x, event->y, &path, &column, NULL, NULL))
       gtk_tree_selection_unselect_all (selection);
 
+  /* make sure that rubber banding is enabled */
+  gtk_tree_view_set_rubber_banding (tree_view, TRUE);
+
   /* if the user clicked on a row with the left button */
   if (path != NULL && event->type == GDK_BUTTON_PRESS && event->button == 1)
     {
diff --git a/thunar/thunar-dialogs.c b/thunar/thunar-dialogs.c
index 0083bdcf..78850ed4 100644
--- a/thunar/thunar-dialogs.c
+++ b/thunar/thunar-dialogs.c
@@ -173,6 +173,10 @@ thunar_dialogs_show_rename_file (gpointer    parent,
   /* resize the dialog to make long names fit as much as possible */
   gtk_window_set_default_size (GTK_WINDOW (dialog), CLAMP (layout_width, 300, parent_width), -1);
 
+  /* automatically close the dialog when the file is destroyed */
+  g_signal_connect_swapped (G_OBJECT (file), "destroy",
+                            G_CALLBACK (gtk_widget_destroy), dialog);
+
   /* run the dialog */
   response = gtk_dialog_run (GTK_DIALOG (dialog));
   if (G_LIKELY (response == GTK_RESPONSE_OK))
@@ -192,7 +196,13 @@ thunar_dialogs_show_rename_file (gpointer    parent,
     }
 
   /* cleanup */
-  gtk_widget_destroy (dialog);
+  if (G_LIKELY (response != GTK_RESPONSE_NONE))
+    {
+      /* unregister handler */
+      g_signal_handlers_disconnect_by_func (G_OBJECT (file), gtk_widget_destroy, dialog);
+
+      gtk_widget_destroy (dialog);
+    }
 
   return job;
 }
@@ -258,8 +268,8 @@ thunar_dialogs_show_about (GtkWindow   *parent,
                          "copyright", "Copyright \302\251 2004-2011 Benedikt Meurer\n"
                                       "Copyright \302\251 2009-2011 Jannis Pohlmann\n"
                                       "Copyright \302\251 2009-2012 Nick Schermer\n"
-                                      "Copyright \302\251 2017-2018 Alexander Schwinn\n"
-                                      "Copyright \302\251 2017-2018 Andre Miranda",
+                                      "Copyright \302\251 2017-2019 Alexander Schwinn\n"
+                                      "Copyright \302\251 2017-2019 Andre Miranda",
                          "destroy-with-parent", TRUE,
                          "documenters", documenters,
                          "license", XFCE_LICENSE_GPL,
@@ -304,6 +314,8 @@ thunar_dialogs_show_error (gpointer      parent,
   GdkScreen *screen;
   va_list    args;
   gchar     *primary_text;
+  GList     *children;
+  GList     *lp;
 
   _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent));
 
@@ -335,12 +347,21 @@ thunar_dialogs_show_error (gpointer      parent,
   if (G_LIKELY (error != NULL))
     gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s.", error->message);
 
+  children = gtk_container_get_children (
+    GTK_CONTAINER (gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog))));
+
+  /* enable wrap for labels */
+  for (lp = children; lp != NULL; lp = lp->next)
+    if (GTK_IS_LABEL (lp->data))
+      gtk_label_set_line_wrap_mode (GTK_LABEL (lp->data), PANGO_WRAP_WORD_CHAR);
+
   /* display the dialog */
   gtk_dialog_run (GTK_DIALOG (dialog));
 
   /* cleanup */
   gtk_widget_destroy (dialog);
   g_free (primary_text);
+  g_list_free (children);
 }
 
 
@@ -497,6 +518,19 @@ thunar_dialogs_show_job_ask (GtkWindow        *parent,
 
 
 
+static void thunar_dialogs_show_job_ask_replace_callback (GtkWidget *button,
+                                                          gpointer   user_data)
+{
+  gint response;
+
+  _thunar_return_if_fail (GTK_IS_DIALOG (user_data));
+
+  response = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), "response-id"));
+  gtk_dialog_response (GTK_DIALOG (user_data), response);
+}
+
+
+
 /**
  * thunar_dialogs_show_job_ask_replace:
  * @parent   : the parent #GtkWindow or %NULL.
@@ -522,6 +556,13 @@ thunar_dialogs_show_job_ask_replace (GtkWindow  *parent,
   GtkWidget         *grid;
   GtkWidget         *image;
   GtkWidget         *label;
+  GtkWidget         *content_area;
+  GtkWidget         *cancel_button;
+  GtkWidget         *button_box;
+  GtkWidget         *skipall_button;
+  GtkWidget         *skip_button;
+  GtkWidget         *replaceall_button;
+  GtkWidget         *replace_button;
   GdkPixbuf         *icon;
   gchar             *date_custom_style;
   gchar             *date_string;
@@ -542,17 +583,13 @@ thunar_dialogs_show_job_ask_replace (GtkWindow  *parent,
   g_object_unref (G_OBJECT (preferences));
 
   /* setup the confirmation dialog */
-  dialog = gtk_dialog_new_with_buttons (_("Confirm to replace files"),
-                                        parent,
-                                        GTK_DIALOG_MODAL
-                                        | GTK_DIALOG_DESTROY_WITH_PARENT,
-                                        _("_Cancel"), GTK_RESPONSE_CANCEL,
-                                        _("S_kip All"), THUNAR_JOB_RESPONSE_NO_ALL,
-                                        _("_Skip"), THUNAR_JOB_RESPONSE_NO,
-                                        _("Replace _All"), THUNAR_JOB_RESPONSE_YES_ALL,
-                                        _("_Replace"), THUNAR_JOB_RESPONSE_YES,
-                                        NULL);
+  dialog = gtk_dialog_new();
+  gtk_window_set_title (GTK_WINDOW (dialog), _("Confirm to replace files"));
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
+  gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
+  gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
   gtk_dialog_set_default_response (GTK_DIALOG (dialog), THUNAR_JOB_RESPONSE_YES);
+  content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
 
   /* determine the icon factory to use */
   icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (dialog));
@@ -562,9 +599,40 @@ thunar_dialogs_show_job_ask_replace (GtkWindow  *parent,
   gtk_grid_set_column_spacing (GTK_GRID (grid), 5);
   gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
   gtk_container_set_border_width (GTK_CONTAINER (grid), 10);
-  gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), grid, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (content_area), grid, TRUE, FALSE, 0);
   gtk_widget_show (grid);
 
+  /* set up the action area buttons ourself */
+  button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
+
+  cancel_button     = gtk_button_new_with_mnemonic (_("_Cancel"));
+  skipall_button    = gtk_button_new_with_mnemonic (_("S_kip All"));
+  skip_button       = gtk_button_new_with_mnemonic (_("_Skip"));
+  replaceall_button = gtk_button_new_with_mnemonic (_("Replace _All"));
+  replace_button    = gtk_button_new_with_mnemonic (_("_Replace"));
+
+  g_signal_connect (cancel_button,      "clicked", G_CALLBACK (thunar_dialogs_show_job_ask_replace_callback), dialog);
+  g_signal_connect (skipall_button,     "clicked", G_CALLBACK (thunar_dialogs_show_job_ask_replace_callback), dialog);
+  g_signal_connect (skip_button,        "clicked", G_CALLBACK (thunar_dialogs_show_job_ask_replace_callback), dialog);
+  g_signal_connect (replaceall_button,  "clicked", G_CALLBACK (thunar_dialogs_show_job_ask_replace_callback), dialog);
+  g_signal_connect (replace_button,     "clicked", G_CALLBACK (thunar_dialogs_show_job_ask_replace_callback), dialog);
+
+  g_object_set_data (G_OBJECT (cancel_button),     "response-id", GINT_TO_POINTER (GTK_RESPONSE_CANCEL));
+  g_object_set_data (G_OBJECT (skipall_button),    "response-id", GINT_TO_POINTER (THUNAR_JOB_RESPONSE_NO_ALL));
+  g_object_set_data (G_OBJECT (skip_button),       "response-id", GINT_TO_POINTER (THUNAR_JOB_RESPONSE_NO));
+  g_object_set_data (G_OBJECT (replaceall_button), "response-id", GINT_TO_POINTER (THUNAR_JOB_RESPONSE_YES_ALL));
+  g_object_set_data (G_OBJECT (replace_button),    "response-id", GINT_TO_POINTER (THUNAR_JOB_RESPONSE_YES));
+
+  gtk_container_add (GTK_CONTAINER (button_box), cancel_button);
+  gtk_container_add (GTK_CONTAINER (button_box), skipall_button);
+  gtk_container_add (GTK_CONTAINER (button_box), skip_button);
+  gtk_container_add (GTK_CONTAINER (button_box), replaceall_button);
+  gtk_container_add (GTK_CONTAINER (button_box), replace_button);
+  gtk_container_add (GTK_CONTAINER (content_area), button_box);
+  gtk_widget_set_halign (button_box, GTK_ALIGN_CENTER);
+  gtk_box_set_spacing (GTK_BOX (button_box), 5);
+  gtk_widget_show_all (button_box);
+
   image = gtk_image_new_from_icon_name ("stock_folder-copy", GTK_ICON_SIZE_BUTTON);
   gtk_widget_set_halign (image, GTK_ALIGN_CENTER);
   gtk_widget_set_valign (image, GTK_ALIGN_START);
@@ -596,6 +664,7 @@ thunar_dialogs_show_job_ask_replace (GtkWindow  *parent,
   gtk_label_set_xalign (GTK_LABEL (label), 0.0f);
   gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_big ());
   gtk_widget_set_hexpand (label, TRUE);
+  gtk_label_set_selectable(GTK_LABEL (label), TRUE);
   gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 2, 1);
   gtk_widget_show (label);
   g_free (text);
diff --git a/thunar/thunar-emblem-chooser.c b/thunar/thunar-emblem-chooser.c
index 30953d63..1a7cdfee 100644
--- a/thunar/thunar-emblem-chooser.c
+++ b/thunar/thunar-emblem-chooser.c
@@ -230,7 +230,9 @@ thunar_emblem_chooser_unrealize (GtkWidget *widget)
   ThunarEmblemChooser *chooser = THUNAR_EMBLEM_CHOOSER (widget);
 
   /* drop all check buttons */
-  gtk_container_foreach (GTK_CONTAINER (chooser->table), (GtkCallback) gtk_widget_destroy, NULL);
+  gtk_container_foreach (GTK_CONTAINER (chooser->table),
+                         (GtkCallback) (void (*)(void)) gtk_widget_destroy,
+                         NULL);
 
   /* release our reference on the icon theme */
   g_signal_handlers_disconnect_by_func (G_OBJECT (chooser->icon_theme), thunar_emblem_chooser_theme_changed, chooser);
@@ -276,7 +278,7 @@ thunar_emblem_chooser_button_toggled (GtkToggleButton     *button,
       if (gtk_toggle_button_get_active (button))
         {
           /* check if we need to add the new emblem */
-          if (g_list_find_custom (emblem_names, emblem_name, (GCompareFunc) strcmp) == NULL)
+          if (g_list_find_custom (emblem_names, emblem_name, (GCompareFunc) (void (*)(void)) strcmp) == NULL)
             {
               emblem_names = g_list_append (emblem_names, (gchar *) emblem_name);
               is_modified = TRUE;
@@ -284,7 +286,7 @@ thunar_emblem_chooser_button_toggled (GtkToggleButton     *button,
         }
       else
         {
-          delete_link = g_list_find_custom (emblem_names, emblem_name, (GCompareFunc) strcmp);
+          delete_link = g_list_find_custom (emblem_names, emblem_name, (GCompareFunc) (void (*)(void)) strcmp);
           if (delete_link != NULL)
             {
               emblem_names = g_list_delete_link (emblem_names, delete_link);
@@ -381,7 +383,9 @@ thunar_emblem_chooser_theme_changed (GtkIconTheme        *icon_theme,
   _thunar_return_if_fail (chooser->icon_theme == icon_theme);
 
   /* drop the current buttons */
-  gtk_container_foreach (GTK_CONTAINER (chooser->table), (GtkCallback) gtk_widget_destroy, NULL);
+  gtk_container_foreach (GTK_CONTAINER (chooser->table),
+                         (GtkCallback) (void (*)(void)) gtk_widget_destroy,
+                         NULL);
 
   /* create buttons for the new theme */
   thunar_emblem_chooser_create_buttons (chooser);
@@ -400,7 +404,7 @@ thunar_emblem_chooser_create_buttons (ThunarEmblemChooser *chooser)
   emblems = gtk_icon_theme_list_icons (chooser->icon_theme, "Emblems");
 
   /* sort the emblem list */
-  emblems = g_list_sort (emblems, (GCompareFunc) g_ascii_strcasecmp);
+  emblems = g_list_sort (emblems, (GCompareFunc) (void (*)(void)) g_ascii_strcasecmp);
 
   /* create buttons for the emblems */
   for (lp = emblems; lp != NULL; lp = lp->next)
diff --git a/thunar/thunar-exec.c b/thunar/thunar-exec.c
index edbe270e..685783c0 100644
--- a/thunar/thunar-exec.c
+++ b/thunar/thunar-exec.c
@@ -104,7 +104,7 @@ te_string_append_quoted_uri (GString *string,
  * @error     : return location for errors or %NULL.
  *
  * Substitutes <literal>Exec</literal> parameter variables according
- * to the <ulink href="http://freedesktop.org/wiki/Standards_2fdesktop_2dentry_2dspec";
+ * to the <ulink href="https://freedesktop.org/wiki/Specifications/desktop-entry-spec";
  * type="http">Desktop Entry Specification</ulink> and returns the
  * parsed argument vector (in @argv) and the number of items placed
  * into @argv (in @argc).
diff --git a/thunar/thunar-file.c b/thunar/thunar-file.c
index d9147aa7..1ac9a1e4 100644
--- a/thunar/thunar-file.c
+++ b/thunar/thunar-file.c
@@ -1822,7 +1822,7 @@ thunar_file_launch (ThunarFile  *file,
   /* HACK: check if we're not trying to launch another file manager again, possibly
    * ourselfs which will end in a loop */
   if (g_strcmp0 (g_app_info_get_id (app_info), "exo-file-manager.desktop") == 0
-      || g_strcmp0 (g_app_info_get_id (app_info), "Thunar.desktop") == 0
+      || g_strcmp0 (g_app_info_get_id (app_info), "thunar.desktop") == 0
       || g_strcmp0 (g_app_info_get_name (app_info), "exo-file-manager") == 0)
     {
       g_object_unref (G_OBJECT (app_info));
@@ -2031,11 +2031,18 @@ thunar_file_accepts_drop (ThunarFile     *file,
   /* default to whatever GTK+ thinks for the suggested action */
   suggested_action = gdk_drag_context_get_suggested_action (context);
 
+  /* get the possible actions */
+  actions = gdk_drag_context_get_actions (context);
+
+  /* when the option to ask the user is set, make it the preferred action */
+  if (G_UNLIKELY ((actions & GDK_ACTION_ASK) != 0))
+    suggested_action = GDK_ACTION_ASK;
+
   /* check if we have a writable directory here or an executable file */
   if (thunar_file_is_directory (file) && thunar_file_is_writable (file))
     {
       /* determine the possible actions */
-      actions = gdk_drag_context_get_actions (context) & (GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK);
+      actions &= (GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK);
 
       /* cannot create symbolic links in the trash or copy to the trash */
       if (thunar_file_is_trashed (file))
@@ -2113,7 +2120,7 @@ thunar_file_accepts_drop (ThunarFile     *file,
   else if (thunar_file_is_executable (file))
     {
       /* determine the possible actions */
-      actions = gdk_drag_context_get_actions (context) & (GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_PRIVATE);
+      actions &= (GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_PRIVATE);
     }
   else
     return 0;
@@ -3384,7 +3391,7 @@ thunar_file_get_emblem_names (ThunarFile *file)
         : 0;
 
   /* we add "cant-read" if either (a) the file is not readable or (b) a directory, that lacks the
-   * x-bit, see http://bugzilla.xfce.org/show_bug.cgi?id=1408 for the details about this change.
+   * x-bit, see https://bugzilla.xfce.org/show_bug.cgi?id=1408 for the details about this change.
    */
   if (!thunar_file_is_readable (file)
       || (thunar_file_is_directory (file)
diff --git a/thunar/thunar-folder.c b/thunar/thunar-folder.c
index 7ca50b06..2d6134f4 100644
--- a/thunar/thunar-folder.c
+++ b/thunar/thunar-folder.c
@@ -132,6 +132,22 @@ G_DEFINE_TYPE (ThunarFolder, thunar_folder, G_TYPE_OBJECT)
 
 
 
+static void
+thunar_folder_constructed (GObject *object)
+{
+  ThunarFolder *folder = THUNAR_FOLDER (object);
+
+  /* add us to the folder alteration monitor */
+  folder->monitor = g_file_monitor_directory (thunar_file_get_file (folder->corresponding_file),
+                                          G_FILE_MONITOR_SEND_MOVED, NULL, NULL);
+  if (G_LIKELY (folder->monitor != NULL))
+      g_signal_connect (folder->monitor, "changed", G_CALLBACK (thunar_folder_monitor), folder);
+
+  G_OBJECT_CLASS (thunar_folder_parent_class)->constructed (object);
+}
+
+
+
 static void
 thunar_folder_class_init (ThunarFolderClass *klass)
 {
@@ -142,6 +158,7 @@ thunar_folder_class_init (ThunarFolderClass *klass)
   gobject_class->finalize = thunar_folder_finalize;
   gobject_class->get_property = thunar_folder_get_property;
   gobject_class->set_property = thunar_folder_set_property;
+  gobject_class->constructed = thunar_folder_constructed;
 
   klass->destroy = thunar_folder_real_destroy;
 
@@ -359,8 +376,6 @@ thunar_folder_set_property (GObject      *object,
   switch (prop_id)
     {
     case PROP_CORRESPONDING_FILE:
-      if (folder->corresponding_file)
-        thunar_file_unwatch (folder->corresponding_file);
       folder->corresponding_file = g_value_dup_object (value);
       if (folder->corresponding_file)
         thunar_file_watch (folder->corresponding_file);
@@ -407,7 +422,6 @@ thunar_folder_files_ready (ThunarJob    *job,
 {
   _thunar_return_val_if_fail (THUNAR_IS_FOLDER (folder), FALSE);
   _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
-  _thunar_return_val_if_fail (folder->monitor == NULL, FALSE);
 
   /* merge the list with the existing list of new files */
   folder->new_files = g_list_concat (folder->new_files, files);
@@ -485,7 +499,6 @@ thunar_folder_finished (ExoJob       *job,
   _thunar_return_if_fail (THUNAR_IS_FOLDER (folder));
   _thunar_return_if_fail (THUNAR_IS_JOB (job));
   _thunar_return_if_fail (THUNAR_IS_FILE (folder->corresponding_file));
-  _thunar_return_if_fail (folder->monitor == NULL);
   _thunar_return_if_fail (folder->content_type_idle_id == 0);
 
   /* check if we need to merge new files with existing files */
@@ -573,19 +586,16 @@ thunar_folder_finished (ExoJob       *job,
     }
 
   /* we did it, the folder is loaded */
-  g_signal_handlers_disconnect_matched (folder->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder);
-  g_object_unref (folder->job);
-  folder->job = NULL;
+  if (G_LIKELY (folder->job != NULL))
+    {
+      g_signal_handlers_disconnect_matched (folder->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder);
+      g_object_unref (folder->job);
+      folder->job = NULL;
+    }
 
   /* restart the content type idle loader */
   thunar_folder_content_type_loader (folder);
 
-  /* add us to the file alteration monitor */
-  folder->monitor = g_file_monitor_directory (thunar_file_get_file (folder->corresponding_file),
-                                              G_FILE_MONITOR_SEND_MOVED, NULL, NULL);
-  if (G_LIKELY (folder->monitor != NULL))
-    g_signal_connect (folder->monitor, "changed", G_CALLBACK (thunar_folder_monitor), folder);
-
   /* tell the consumers that we have loaded the directory */
   g_object_notify (G_OBJECT (folder), "loading");
 }
@@ -733,7 +743,6 @@ thunar_folder_monitor (GFileMonitor     *monitor,
   _thunar_return_if_fail (G_IS_FILE_MONITOR (monitor));
   _thunar_return_if_fail (THUNAR_IS_FOLDER (folder));
   _thunar_return_if_fail (folder->monitor == monitor);
-  _thunar_return_if_fail (folder->job == NULL);
   _thunar_return_if_fail (THUNAR_IS_FILE (folder->corresponding_file));
   _thunar_return_if_fail (G_IS_FILE (event_file));
 
@@ -762,6 +771,9 @@ thunar_folder_monitor (GFileMonitor     *monitor,
               /* tell others about the new file */
               list.data = file; list.next = list.prev = NULL;
               g_signal_emit (G_OBJECT (folder), folder_signals[FILES_ADDED], 0, &list);
+
+              /* load the new file */
+              thunar_file_reload (file);
             }
         }
       else if (lp != NULL)
@@ -811,9 +823,6 @@ thunar_folder_monitor (GFileMonitor     *monitor,
                       g_object_unref (file);
                     }
                 }
-
-              /* reload the folder of the source file */
-              thunar_file_reload (folder->corresponding_file);
             }
           else
             {
@@ -990,15 +999,6 @@ thunar_folder_reload (ThunarFolder *folder,
       folder->job = NULL;
     }
 
-  /* disconnect from the file alteration monitor */
-  if (G_UNLIKELY (folder->monitor != NULL))
-    {
-      g_signal_handlers_disconnect_matched (folder->monitor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder);
-      g_file_monitor_cancel (folder->monitor);
-      g_object_unref (folder->monitor);
-      folder->monitor = NULL;
-    }
-
   /* reset the new_files list */
   thunar_g_file_list_free (folder->new_files);
   folder->new_files = NULL;
diff --git a/thunar/thunar-gdk-extensions.c b/thunar/thunar-gdk-extensions.c
index 18cfb3b6..279382cb 100644
--- a/thunar/thunar-gdk-extensions.c
+++ b/thunar/thunar-gdk-extensions.c
@@ -191,6 +191,12 @@ thunar_gdk_screen_open (const gchar *display_name,
           display = dp->data;
           break;
         }
+      /* This second comparison will as well match the short notation, ":0" with the long notation ":0.0" */
+      if (strncmp (other_name, display_name, strlen (other_name)) == 0)
+        {
+          display = dp->data;
+          break;
+        }
     }
   g_slist_free (displays);
 
diff --git a/thunar/thunar-gio-extensions.c b/thunar/thunar-gio-extensions.c
index 629ec018..28988b62 100644
--- a/thunar/thunar-gio-extensions.c
+++ b/thunar/thunar-gio-extensions.c
@@ -552,11 +552,14 @@ thunar_g_app_info_launch (GAppInfo          *info,
                           GError           **error)
 {
   ThunarFile   *file;
+  GAppInfo     *default_app_info;
+  GList        *recommended_app_infos;
   GList        *lp;
   const gchar  *content_type;
   gboolean      result = FALSE;
   gchar        *new_path = NULL;
   gchar        *old_path = NULL;
+  gboolean      skip_app_info_update;
 
   _thunar_return_val_if_fail (G_IS_APP_INFO (info), FALSE);
   _thunar_return_val_if_fail (working_directory == NULL || G_IS_FILE (working_directory), FALSE);
@@ -564,6 +567,8 @@ thunar_g_app_info_launch (GAppInfo          *info,
   _thunar_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), FALSE);
   _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
+  skip_app_info_update = (g_object_get_data (G_OBJECT (info), "skip-app-info-update") != NULL);
+
   /* check if we want to set the working directory of the spawned app */
   if (working_directory != NULL)
     {
@@ -587,17 +592,44 @@ thunar_g_app_info_launch (GAppInfo          *info,
     {
       for (lp = path_list; lp != NULL; lp = lp->next)
         {
+          gboolean update_app_info = !skip_app_info_update;
+
           file = thunar_file_get (lp->data, NULL);
-          if (file != NULL)
+          if (file == NULL)
+            continue;
+
+          content_type = thunar_file_get_content_type (file);
+
+          /* determine default application */
+          default_app_info = thunar_file_get_default_handler (file);
+          if (default_app_info != NULL)
             {
-              content_type = thunar_file_get_content_type (file);
+              /* check if the application is the default one */
+              if (g_app_info_equal (info, default_app_info))
+                update_app_info = FALSE;
+              g_object_unref (default_app_info);
+            }
 
-              /* emit "changed" on the file if we successfully changed the last used application */
-              if (g_app_info_set_as_last_used_for_type (info, content_type, NULL))
-                thunar_file_changed (file);
+          if (update_app_info)
+            {
+              /* obtain list of last used applications */
+              recommended_app_infos = g_app_info_get_recommended_for_type (content_type);
+              if (recommended_app_infos != NULL)
+                {
+                  /* check if the application is already the last used one
+                   * by comparing it with the first entry in the list */
+                  if (g_app_info_equal (info, recommended_app_infos->data))
+                    update_app_info = FALSE;
 
-              g_object_unref (file);
+                  g_list_free (recommended_app_infos);
+                }
             }
+
+          /* emit "changed" on the file if we successfully changed the last used application */
+          if (update_app_info && g_app_info_set_as_last_used_for_type (info, content_type, NULL))
+            thunar_file_changed (file);
+
+          g_object_unref (file);
         }
     }
 
diff --git a/thunar/thunar-gtk-extensions.c b/thunar/thunar-gtk-extensions.c
index 4852c118..f2a0c226 100644
--- a/thunar/thunar-gtk-extensions.c
+++ b/thunar/thunar-gtk-extensions.c
@@ -131,27 +131,88 @@ thunar_gtk_label_set_a11y_relation (GtkLabel  *label,
  * thunar_gtk_menu_run:
  * @menu : a #GtkMenu.
  *
- * A simple wrapper around gtk_menu_popup_at_pointer(), which takes care on the
- * menu and returns only after the @menu was deactivated.
+ * Conveniance wrapper for thunar_gtk_menu_run_at_event_pointer, to run a menu for the current event
+ **/
+void
+thunar_gtk_menu_run (GtkMenu *menu)
+{
+  GdkEvent *event = gtk_get_current_event ();
+  thunar_gtk_menu_run_at_event (menu, event);
+  gdk_event_free (event);
+}
+
+
+
+#if GTK_CHECK_VERSION (3, 24, 8)
+static void
+moved_to_rect_cb (GdkWindow          *window,
+                  const GdkRectangle *flipped_rect,
+                  const GdkRectangle *final_rect,
+                  gboolean            flipped_x,
+                  gboolean            flipped_y,
+                  GtkMenu            *menu)
+{
+    g_signal_emit_by_name (menu, "popped-up", 0, flipped_rect, final_rect, flipped_x, flipped_y);
+    g_signal_stop_emission_by_name (window, "moved-to-rect");
+}
+
+
+
+static void
+popup_menu_realized (GtkWidget *menu,
+                     gpointer   user_data)
+{
+    GdkWindow *toplevel = gtk_widget_get_window (gtk_widget_get_toplevel (menu));
+    g_signal_handlers_disconnect_by_func (toplevel, moved_to_rect_cb, menu);
+    g_signal_connect (toplevel, "moved-to-rect", G_CALLBACK (moved_to_rect_cb), menu);
+}
+#endif
+
+
+
+/**
+ * thunar_gtk_menu_run_at_event:
+ * @menu  : a #GtkMenu.
+ * @event : a #GdkEvent which may be NULL if no previous event was stored.
+ *
+ * A simple wrapper around gtk_menu_popup_at_pointer(), which runs the @menu in a separate
+ * main loop and returns only after the @menu was deactivated.
  *
  * This method automatically takes over the floating reference of @menu if any and
  * releases it on return. That means if you created the menu via gtk_menu_new() you'll
  * not need to take care of destroying the menu later.
+ * 
  **/
 void
-thunar_gtk_menu_run (GtkMenu *menu)
+thunar_gtk_menu_run_at_event (GtkMenu *menu,
+                              GdkEvent *event)
 {
-  GdkEvent  *event;
+  GMainLoop *loop;
+  gulong     signal_id;
 
   _thunar_return_if_fail (GTK_IS_MENU (menu));
 
   /* take over the floating reference on the menu */
   g_object_ref_sink (G_OBJECT (menu));
 
-  event = gtk_get_current_event ();
+  /* run an internal main loop */
+  loop = g_main_loop_new (NULL, FALSE);
+  signal_id = g_signal_connect_swapped (G_OBJECT (menu), "deactivate", G_CALLBACK (g_main_loop_quit), loop);
+
+#if GTK_CHECK_VERSION (3, 24, 8)
+    /* Workaround for incorrect popup menus size */
+    g_signal_connect (G_OBJECT (menu), "realize", G_CALLBACK (popup_menu_realized), NULL);
+    gtk_widget_realize (GTK_WIDGET (menu));
+#endif
+
   gtk_menu_popup_at_pointer (menu, event);
-  gdk_event_free (event);
   gtk_menu_reposition (menu);
+  gtk_grab_add (GTK_WIDGET (menu));
+  g_main_loop_run (loop);
+  g_main_loop_unref (loop);
+  gtk_grab_remove (GTK_WIDGET (menu));
+
+  g_signal_handler_disconnect (G_OBJECT (menu), signal_id);
 
   /* release the menu reference */
   g_object_unref (G_OBJECT (menu));
diff --git a/thunar/thunar-gtk-extensions.h b/thunar/thunar-gtk-extensions.h
index a264595c..98e0c30f 100644
--- a/thunar/thunar-gtk-extensions.h
+++ b/thunar/thunar-gtk-extensions.h
@@ -37,6 +37,9 @@ void             thunar_gtk_label_set_a11y_relation           (GtkLabel
 
 void             thunar_gtk_menu_run                          (GtkMenu            *menu);
 
+void             thunar_gtk_menu_run_at_event                 (GtkMenu            *menu,
+                                                               GdkEvent           *event);
+
 GtkAction       *thunar_gtk_ui_manager_get_action_by_name     (GtkUIManager       *ui_manager,
                                                                const gchar        *action_name);
 
diff --git a/thunar/thunar-icon-factory.c b/thunar/thunar-icon-factory.c
index 9b899c4f..16a5556a 100644
--- a/thunar/thunar-icon-factory.c
+++ b/thunar/thunar-icon-factory.c
@@ -361,7 +361,9 @@ thunar_icon_factory_sweep_timer (gpointer user_data)
 THUNAR_THREADS_ENTER
 
   /* ditch all icons whose ref_count is 1 */
-  g_hash_table_foreach_remove (factory->icon_cache, (GHRFunc) thunar_icon_check_sweep, factory);
+  g_hash_table_foreach_remove (factory->icon_cache,
+                               (GHRFunc) (void (*)(void)) thunar_icon_check_sweep,
+                               factory);
 
 THUNAR_THREADS_LEAVE
 
diff --git a/thunar/thunar-icon-view.c b/thunar/thunar-icon-view.c
index 5dcc71ef..5a97f646 100644
--- a/thunar/thunar-icon-view.c
+++ b/thunar/thunar-icon-view.c
@@ -98,7 +98,7 @@ thunar_icon_view_init (ThunarIconView *icon_view)
 {
   /* setup the icon renderer */
   g_object_set (G_OBJECT (THUNAR_STANDARD_VIEW (icon_view)->icon_renderer),
-                "ypad", 3u,
+                "ypad", 1u,
                 NULL);
 
   /* setup the name renderer */
@@ -126,7 +126,7 @@ thunar_icon_view_set_property (GObject      *object,
       if (G_UNLIKELY (g_value_get_boolean (value)))
         {
           exo_icon_view_set_orientation (EXO_ICON_VIEW (gtk_bin_get_child (GTK_BIN (standard_view))), GTK_ORIENTATION_HORIZONTAL);
-          g_object_set (G_OBJECT (standard_view->name_renderer), "wrap-width", 128, "yalign", 0.5f, "alignment", PANGO_ALIGN_LEFT, NULL);
+          g_object_set (G_OBJECT (standard_view->name_renderer), "wrap-width", 128, "yalign", 0.5f, "xalign", 0.0f, "alignment", PANGO_ALIGN_LEFT, NULL);
 
           /* disconnect the "zoom-level" signal handler, since we're using a fixed wrap-width here */
           g_signal_handlers_disconnect_by_func (object, thunar_icon_view_zoom_level_changed, NULL);
@@ -134,7 +134,7 @@ thunar_icon_view_set_property (GObject      *object,
       else
         {
           exo_icon_view_set_orientation (EXO_ICON_VIEW (gtk_bin_get_child (GTK_BIN (standard_view))), GTK_ORIENTATION_VERTICAL);
-          g_object_set (G_OBJECT (standard_view->name_renderer), "yalign", 0.0f, "alignment", PANGO_ALIGN_CENTER, NULL);
+          g_object_set (G_OBJECT (standard_view->name_renderer), "yalign", 0.0f, "xalign", 0.5f, "alignment", PANGO_ALIGN_CENTER, NULL);
 
           /* connect the "zoom-level" signal handler as the wrap-width is now synced with the "zoom-level" */
           g_signal_connect (object, "notify::zoom-level", G_CALLBACK (thunar_icon_view_zoom_level_changed), NULL);
diff --git a/thunar/thunar-image.c b/thunar/thunar-image.c
index cff52052..e3fe3aa6 100644
--- a/thunar/thunar-image.c
+++ b/thunar/thunar-image.c
@@ -33,10 +33,6 @@
 
 
 
-#define THUNAR_IMAGE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNAR_TYPE_IMAGE, ThunarImagePrivate))
-
-
-
 /* Property identifiers */
 enum
 {
@@ -81,7 +77,7 @@ struct _ThunarImagePrivate
 
 
 
-G_DEFINE_TYPE (ThunarImage, thunar_image, GTK_TYPE_IMAGE);
+G_DEFINE_TYPE_WITH_PRIVATE (ThunarImage, thunar_image, GTK_TYPE_IMAGE);
 
 
 
@@ -90,8 +86,6 @@ thunar_image_class_init (ThunarImageClass *klass)
 {
   GObjectClass *gobject_class;
 
-  g_type_class_add_private (klass, sizeof (ThunarImagePrivate));
-
   gobject_class = G_OBJECT_CLASS (klass);
   gobject_class->finalize = thunar_image_finalize;
   gobject_class->get_property = thunar_image_get_property;
@@ -110,7 +104,7 @@ thunar_image_class_init (ThunarImageClass *klass)
 static void
 thunar_image_init (ThunarImage *image)
 {
-  image->priv = THUNAR_IMAGE_GET_PRIVATE (image);
+  image->priv = thunar_image_get_instance_private (image);
   image->priv->file = NULL;
 
   image->priv->monitor = thunar_file_monitor_get_default ();
diff --git a/thunar/thunar-io-jobs.c b/thunar/thunar-io-jobs.c
index eaaa7072..4f641840 100644
--- a/thunar/thunar-io-jobs.c
+++ b/thunar/thunar-io-jobs.c
@@ -22,7 +22,12 @@
 #include <config.h>
 #endif
 
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
 #include <gio/gio.h>
+#include <glib/gstdio.h>
 
 #include <thunar/thunar-application.h>
 #include <thunar/thunar-enum-types.h>
@@ -83,6 +88,34 @@ _tij_collect_nofollow (ThunarJob *job,
 
 
 
+static gboolean
+_tij_delete_file (GFile        *file,
+                  GCancellable *cancellable,
+                  GError      **error)
+{
+  gchar *path;
+
+  if (!g_file_is_native (file))
+    return g_file_delete (file, cancellable, error);
+
+  /* adapted from g_local_file_delete of gio/glocalfile.c */
+  path = g_file_get_path (file);
+
+  if (g_remove (path) == 0)
+    {
+      g_free (path);
+      return TRUE;
+    }
+
+  g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+               _("Error removing file: %s"), g_strerror (errno));
+
+  g_free (path);
+  return FALSE;
+}
+
+
+
 static gboolean
 _thunar_io_jobs_create (ThunarJob  *job,
                         GArray     *param_values,
@@ -96,6 +129,7 @@ _thunar_io_jobs_create (ThunarJob  *job,
   GList             *lp;
   gchar             *base_name;
   gchar             *display_name;
+  guint              n_processed = 0;
   GFile             *template_file;
   GFileInputStream  *template_stream = NULL;
 
@@ -126,12 +160,12 @@ _thunar_io_jobs_create (ThunarJob  *job,
   /* iterate over all files in the list */
   for (lp = file_list;
        err == NULL && lp != NULL && !exo_job_is_cancelled (EXO_JOB (job));
-       lp = lp->next)
+       lp = lp->next, n_processed++)
     {
       g_assert (G_IS_FILE (lp->data));
 
       /* update progress information */
-      thunar_job_processing_file (THUNAR_JOB (job), lp);
+      thunar_job_processing_file (THUNAR_JOB (job), lp, n_processed);
 
 again:
       /* try to create the file */
@@ -184,7 +218,7 @@ again:
               if (response == THUNAR_JOB_RESPONSE_YES)
                 {
                   /* try to remove the file. fail if not possible */
-                  if (g_file_delete (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err))
+                  if (_tij_delete_file (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err))
                     goto again;
                 }
 
@@ -272,6 +306,7 @@ _thunar_io_jobs_mkdir (ThunarJob  *job,
   GList            *lp;
   gchar            *base_name;
   gchar            *display_name;
+  guint             n_processed = 0;
 
   _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
   _thunar_return_val_if_fail (param_values != NULL, FALSE);
@@ -285,12 +320,12 @@ _thunar_io_jobs_mkdir (ThunarJob  *job,
 
   for (lp = file_list;
        err == NULL && lp != NULL && !exo_job_is_cancelled (EXO_JOB (job));
-       lp = lp->next)
+       lp = lp->next,  n_processed++)
     {
       g_assert (G_IS_FILE (lp->data));
 
       /* update progress information */
-      thunar_job_processing_file (THUNAR_JOB (job), lp);
+      thunar_job_processing_file (THUNAR_JOB (job), lp, n_processed);
 
 again:
       /* try to create the directory */
@@ -338,7 +373,7 @@ again:
               if (response == THUNAR_JOB_RESPONSE_YES)
                 {
                   /* try to remove the file, fail if not possible */
-                  if (g_file_delete (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err))
+                  if (_tij_delete_file (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err))
                     goto again;
                 }
 
@@ -410,6 +445,7 @@ _thunar_io_jobs_unlink (ThunarJob  *job,
   GList                *lp;
   gchar                *base_name;
   gchar                *display_name;
+  guint                 n_processed = 0;
 
   _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
   _thunar_return_val_if_fail (param_values != NULL, FALSE);
@@ -446,7 +482,9 @@ _thunar_io_jobs_unlink (ThunarJob  *job,
   g_object_unref (application);
 
   /* remove all the files */
-  for (lp = file_list; lp != NULL && !exo_job_is_cancelled (EXO_JOB (job)); lp = lp->next)
+  for (lp = file_list;
+       lp != NULL && !exo_job_is_cancelled (EXO_JOB (job));
+       lp = lp->next, n_processed++)
     {
       g_assert (G_IS_FILE (lp->data));
 
@@ -455,11 +493,11 @@ _thunar_io_jobs_unlink (ThunarJob  *job,
         continue;
 
       /* update progress information */
-      thunar_job_processing_file (THUNAR_JOB (job), lp);
+      thunar_job_processing_file (THUNAR_JOB (job), lp, n_processed);
 
 again:
       /* try to delete the file */
-      if (g_file_delete (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err))
+      if (_tij_delete_file (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err))
         {
           /* notify the thumbnail cache that the corresponding thumbnail can also
            * be deleted now */
@@ -673,7 +711,7 @@ _thunar_io_jobs_link_file (ThunarJob *job,
             {
               /* try to remove the target file. if not possible, err will be set and
                * the while loop will be aborted */
-              g_file_delete (target_file, exo_job_get_cancellable (EXO_JOB (job)), &err);
+              _tij_delete_file (target_file, exo_job_get_cancellable (EXO_JOB (job)), &err);
             }
 
           /* tell the caller that we skipped this file if the user doesn't want to
@@ -708,6 +746,7 @@ _thunar_io_jobs_link (ThunarJob  *job,
   GList                *sp;
   GList                *target_file_list;
   GList                *tp;
+  guint                 n_processed = 0;
 
   _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
   _thunar_return_val_if_fail (param_values != NULL, FALSE);
@@ -728,13 +767,13 @@ _thunar_io_jobs_link (ThunarJob  *job,
   /* process all files */
   for (sp = source_file_list, tp = target_file_list;
        err == NULL && sp != NULL && tp != NULL;
-       sp = sp->next, tp = tp->next)
+       sp = sp->next, tp = tp->next, n_processed++)
     {
       _thunar_assert (G_IS_FILE (sp->data));
       _thunar_assert (G_IS_FILE (tp->data));
 
       /* update progress information */
-      thunar_job_processing_file (THUNAR_JOB (job), sp);
+      thunar_job_processing_file (THUNAR_JOB (job), sp, n_processed);
 
       /* try to create the symbolic link */
       real_target_file = _thunar_io_jobs_link_file (job, sp->data, tp->data, &err);
@@ -799,6 +838,7 @@ _thunar_io_jobs_trash (ThunarJob  *job,
 {
   ThunarThumbnailCache *thumbnail_cache;
   ThunarApplication    *application;
+  ThunarJobResponse     response;
   GError               *err = NULL;
   GList                *file_list;
   GList                *lp;
@@ -825,6 +865,19 @@ _thunar_io_jobs_trash (ThunarJob  *job,
       /* trash the file or folder */
       g_file_trash (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err);
 
+      if (err != NULL)
+        {
+          response = thunar_job_ask_delete (job, "%s", err->message);
+
+          g_clear_error (&err);
+
+          if (response == THUNAR_JOB_RESPONSE_CANCEL)
+            break;
+
+          if (response == THUNAR_JOB_RESPONSE_YES)
+            _tij_delete_file (lp->data, exo_job_get_cancellable (EXO_JOB (job)), &err);
+        }
+
       /* update the thumbnail cache */
       thunar_thumbnail_cache_cleanup_file (thumbnail_cache, lp->data);
     }
@@ -888,6 +941,7 @@ _thunar_io_jobs_chown (ThunarJob  *job,
   GList            *lp;
   gint              uid;
   gint              gid;
+  guint             n_processed = 0;
 
   _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
   _thunar_return_val_if_fail (param_values != NULL, FALSE);
@@ -917,10 +971,10 @@ _thunar_io_jobs_chown (ThunarJob  *job,
   thunar_job_set_total_files (THUNAR_JOB (job), file_list);
 
   /* change the ownership of all files */
-  for (lp = file_list; lp != NULL && err == NULL; lp = lp->next)
+  for (lp = file_list; lp != NULL && err == NULL; lp = lp->next, n_processed++)
     {
       /* update progress information */
-      thunar_job_processing_file (THUNAR_JOB (job), lp);
+      thunar_job_processing_file (THUNAR_JOB (job), lp, n_processed);
 
       /* try to query information about the file */
       info = g_file_query_info (lp->data,
@@ -1000,7 +1054,7 @@ thunar_io_jobs_change_group (GList    *files,
   _thunar_return_val_if_fail (files != NULL, NULL);
 
   /* files are released when the list if destroyed */
-  g_list_foreach (files, (GFunc) g_object_ref, NULL);
+  g_list_foreach (files, (GFunc) (void (*)(void)) g_object_ref, NULL);
 
   return thunar_simple_job_launch (_thunar_io_jobs_chown, 4,
                                    THUNAR_TYPE_G_FILE_LIST, files,
@@ -1022,6 +1076,7 @@ _thunar_io_jobs_chmod (ThunarJob  *job,
   GError           *err = NULL;
   GList            *file_list;
   GList            *lp;
+  guint             n_processed = 0;
   ThunarFileMode    dir_mask;
   ThunarFileMode    dir_mode;
   ThunarFileMode    file_mask;
@@ -1059,10 +1114,10 @@ _thunar_io_jobs_chmod (ThunarJob  *job,
   thunar_job_set_total_files (THUNAR_JOB (job), file_list);
 
   /* change the ownership of all files */
-  for (lp = file_list; lp != NULL && err == NULL; lp = lp->next)
+  for (lp = file_list; lp != NULL && err == NULL; lp = lp->next, n_processed++)
     {
       /* update progress information */
-      thunar_job_processing_file (THUNAR_JOB (job), lp);
+      thunar_job_processing_file (THUNAR_JOB (job), lp, n_processed);
 
       /* try to query information about the file */
       info = g_file_query_info (lp->data,
@@ -1155,7 +1210,7 @@ thunar_io_jobs_change_mode (GList         *files,
   _thunar_return_val_if_fail (files != NULL, NULL);
 
   /* files are released when the list if destroyed */
-  g_list_foreach (files, (GFunc) g_object_ref, NULL);
+  g_list_foreach (files, (GFunc) (void (*)(void)) g_object_ref, NULL);
 
   return thunar_simple_job_launch (_thunar_io_jobs_chmod, 6,
                                    THUNAR_TYPE_G_FILE_LIST, files,
diff --git a/thunar/thunar-io-scan-directory.c b/thunar/thunar-io-scan-directory.c
index 8f81724c..8072db1d 100644
--- a/thunar/thunar-io-scan-directory.c
+++ b/thunar/thunar-io-scan-directory.c
@@ -52,19 +52,19 @@ thunar_io_scan_directory (ThunarJob          *job,
   const gchar     *namespace;
   ThunarFile      *thunar_file;
   gboolean         is_mounted;
+  GCancellable    *cancellable = NULL;
 
-  _thunar_return_val_if_fail (THUNAR_IS_JOB (job), NULL);
   _thunar_return_val_if_fail (G_IS_FILE (file), NULL);
   _thunar_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
   /* abort if the job was cancelled */
-  if (exo_job_set_error_if_cancelled (EXO_JOB (job), error))
+  if (job != NULL && exo_job_set_error_if_cancelled (EXO_JOB (job), error))
     return NULL;
 
   /* don't recurse when we are scanning prior to unlinking and the current
    * file/dir is in the trash. In GVfs, only the top-level directories in
    * the trash can be modified and deleted directly. See
-   * http://bugzilla.xfce.org/show_bug.cgi?id=7147
+   * https://bugzilla.xfce.org/show_bug.cgi?id=7147
    * for more information */
   if (unlinking
       && thunar_g_file_is_trashed (file)
@@ -73,11 +73,14 @@ thunar_io_scan_directory (ThunarJob          *job,
       return NULL;
     }
 
+  if (job != NULL)
+    cancellable = exo_job_get_cancellable (EXO_JOB (job));
+
   /* query the file type */
-  type = g_file_query_file_type (file, flags, exo_job_get_cancellable (EXO_JOB (job)));
+  type = g_file_query_file_type (file, flags, cancellable);
 
   /* abort if the job was cancelled */
-  if (exo_job_set_error_if_cancelled (EXO_JOB (job), error))
+  if (job != NULL && exo_job_set_error_if_cancelled (EXO_JOB (job), error))
     return NULL;
 
   /* ignore non-directory nodes */
@@ -93,8 +96,7 @@ thunar_io_scan_directory (ThunarJob          *job,
 
   /* try to read from the direectory */
   enumerator = g_file_enumerate_children (file, namespace,
-                                          flags, exo_job_get_cancellable (EXO_JOB (job)),
-                                          &err);
+                                          flags, cancellable, &err);
 
   /* abort if there was an error or the job was cancelled */
   if (err != NULL)
@@ -104,12 +106,10 @@ thunar_io_scan_directory (ThunarJob          *job,
     }
 
   /* iterate over children one by one */
-  while (!exo_job_is_cancelled (EXO_JOB (job)))
+  while (job == NULL || !exo_job_is_cancelled (EXO_JOB (job)))
     {
       /* query info of the child */
-      info = g_file_enumerator_next_file (enumerator,
-                                          exo_job_get_cancellable (EXO_JOB (job)),
-                                          &err);
+      info = g_file_enumerator_next_file (enumerator, cancellable, &err);
 
       if (G_UNLIKELY (info == NULL))
         break;
@@ -171,7 +171,7 @@ thunar_io_scan_directory (ThunarJob          *job,
       thunar_g_file_list_free (files);
       return NULL;
     }
-  else if (exo_job_set_error_if_cancelled (EXO_JOB (job), &err))
+  else if (job != NULL && exo_job_set_error_if_cancelled (EXO_JOB (job), &err))
     {
       g_propagate_error (error, err);
       thunar_g_file_list_free (files);
diff --git a/thunar/thunar-job.c b/thunar/thunar-job.c
index 867278ef..88cc36d7 100644
--- a/thunar/thunar-job.c
+++ b/thunar/thunar-job.c
@@ -38,10 +38,6 @@
 
 
 
-#define THUNAR_JOB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNAR_TYPE_JOB, ThunarJobPrivate))
-
-
-
 /* Signal identifiers */
 enum
 {
@@ -68,8 +64,10 @@ struct _ThunarJobPrivate
 {
   ThunarJobResponse earlier_ask_create_response;
   ThunarJobResponse earlier_ask_overwrite_response;
+  ThunarJobResponse earlier_ask_delete_response;
   ThunarJobResponse earlier_ask_skip_response;
   GList            *total_files;
+  guint             n_total_files;
 };
 
 
@@ -78,7 +76,7 @@ static guint job_signals[LAST_SIGNAL];
 
 
 
-G_DEFINE_ABSTRACT_TYPE (ThunarJob, thunar_job, EXO_TYPE_JOB)
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ThunarJob, thunar_job, EXO_TYPE_JOB)
 
 
 
@@ -99,9 +97,6 @@ thunar_job_class_init (ThunarJobClass *klass)
 {
   GObjectClass *gobject_class;
 
-  /* add our private data for this class */
-  g_type_class_add_private (klass, sizeof (ThunarJobPrivate));
-
   gobject_class = G_OBJECT_CLASS (klass);
   gobject_class->finalize = thunar_job_finalize;
 
@@ -209,10 +204,12 @@ thunar_job_class_init (ThunarJobClass *klass)
 static void
 thunar_job_init (ThunarJob *job)
 {
-  job->priv = THUNAR_JOB_GET_PRIVATE (job);
+  job->priv = thunar_job_get_instance_private (job);
   job->priv->earlier_ask_create_response = 0;
   job->priv->earlier_ask_overwrite_response = 0;
+  job->priv->earlier_ask_delete_response = 0;
   job->priv->earlier_ask_skip_response = 0;
+  job->priv->n_total_files = 0;
 }
 
 
@@ -362,6 +359,63 @@ thunar_job_ask_overwrite (ThunarJob   *job,
 
 
 
+ThunarJobResponse
+thunar_job_ask_delete (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;
+
+  /* check if the user said "Delete All" earlier */
+  if (G_UNLIKELY (job->priv->earlier_ask_delete_response == THUNAR_JOB_RESPONSE_YES_ALL))
+    return THUNAR_JOB_RESPONSE_YES;
+
+  /* check if the user said "Delete None" earlier */
+  if (G_UNLIKELY (job->priv->earlier_ask_delete_response == THUNAR_JOB_RESPONSE_NO_ALL))
+    return THUNAR_JOB_RESPONSE_NO;
+
+  /* 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 permanently delete it?"),
+                                     THUNAR_JOB_RESPONSE_YES
+                                     | THUNAR_JOB_RESPONSE_YES_ALL
+                                     | THUNAR_JOB_RESPONSE_NO
+                                     | THUNAR_JOB_RESPONSE_NO_ALL
+                                     | THUNAR_JOB_RESPONSE_CANCEL);
+  va_end (var_args);
+
+  /* remember response for later */
+  job->priv->earlier_ask_delete_response = response;
+
+  /* translate response */
+  switch (response)
+    {
+    case THUNAR_JOB_RESPONSE_YES_ALL:
+      response = THUNAR_JOB_RESPONSE_YES;
+      break;
+
+    case THUNAR_JOB_RESPONSE_NO_ALL:
+      response = THUNAR_JOB_RESPONSE_NO;
+      break;
+
+    default:
+      break;
+    }
+
+  return response;
+}
+
+
+
 ThunarJobResponse
 thunar_job_ask_create (ThunarJob   *job,
                        const gchar *format,
@@ -598,23 +652,26 @@ thunar_job_set_total_files (ThunarJob *job,
   _thunar_return_if_fail (total_files != NULL);
 
   job->priv->total_files = total_files;
+  job->priv->n_total_files = g_list_length (total_files);
 }
 
 
 
 void
 thunar_job_processing_file (ThunarJob *job,
-                            GList     *current_file)
+                            GList     *current_file,
+                            guint      n_processed)
 {
-  GList *lp;
   gchar *base_name;
   gchar *display_name;
-  guint  n_processed;
-  guint  n_total;
 
   _thunar_return_if_fail (THUNAR_IS_JOB (job));
   _thunar_return_if_fail (current_file != NULL);
 
+  /* emit only if n_processed is a multiple of 8 */
+  if ((n_processed % 8) != 0)
+    return;
+
   base_name = g_file_get_basename (current_file->data);
   display_name = g_filename_display_name (base_name);
   g_free (base_name);
@@ -623,20 +680,6 @@ thunar_job_processing_file (ThunarJob *job,
   g_free (display_name);
 
   /* verify that we have total files set */
-  if (G_LIKELY (job->priv->total_files != NULL))
-    {
-      /* determine the number of files processed so far */
-      for (lp = job->priv->total_files, n_processed = 0;
-           lp != current_file;
-           lp = lp->next, n_processed++);
-
-      /* emit only if n_processed is a multiple of 8 */
-      if ((n_processed % 8) == 0)
-        {
-          /* determine the total_number of files */
-          n_total = g_list_length (job->priv->total_files);
-
-          exo_job_percent (EXO_JOB (job), (n_processed * 100.0) / n_total);
-        }
-    }
+  if (G_LIKELY (job->priv->n_total_files > 0))
+    exo_job_percent (EXO_JOB (job), (n_processed * 100.0) / job->priv->n_total_files);
 }
diff --git a/thunar/thunar-job.h b/thunar/thunar-job.h
index f1f636bd..9c0a7b41 100644
--- a/thunar/thunar-job.h
+++ b/thunar/thunar-job.h
@@ -69,7 +69,8 @@ GType             thunar_job_get_type               (void) G_GNUC_CONST;
 void              thunar_job_set_total_files        (ThunarJob       *job,
                                                      GList           *total_files);
 void              thunar_job_processing_file        (ThunarJob       *job,
-                                                     GList           *current_file);
+                                                     GList           *current_file,
+                                                     guint            n_processed);
 
 ThunarJobResponse thunar_job_ask_create             (ThunarJob       *job,
                                                      const gchar     *format,
@@ -77,6 +78,9 @@ ThunarJobResponse thunar_job_ask_create             (ThunarJob       *job,
 ThunarJobResponse thunar_job_ask_overwrite          (ThunarJob       *job,
                                                      const gchar     *format,
                                                      ...);
+ThunarJobResponse thunar_job_ask_delete             (ThunarJob       *job,
+                                                     const gchar     *format,
+                                                     ...);
 ThunarJobResponse thunar_job_ask_replace            (ThunarJob       *job,
                                                      GFile           *source_path,
                                                      GFile           *target_path,
diff --git a/thunar/thunar-launcher.c b/thunar/thunar-launcher.c
index b34b491b..20789fe7 100644
--- a/thunar/thunar-launcher.c
+++ b/thunar/thunar-launcher.c
@@ -33,6 +33,7 @@
 #include <thunar/thunar-browser.h>
 #include <thunar/thunar-chooser-dialog.h>
 #include <thunar/thunar-dialogs.h>
+#include <thunar/thunar-file-monitor.h>
 #include <thunar/thunar-gio-extensions.h>
 #include <thunar/thunar-gobject-extensions.h>
 #include <thunar/thunar-gtk-extensions.h>
@@ -154,6 +155,8 @@ struct _ThunarLauncher
   ThunarDeviceMonitor    *device_monitor;
   ThunarSendtoModel      *sendto_model;
   guint                   sendto_idle_id;
+
+  ThunarFileMonitor      *file_monitor;
 };
 
 struct _ThunarLauncherMountData
@@ -290,6 +293,10 @@ G_GNUC_END_IGNORE_DEPRECATIONS
   launcher->device_monitor = thunar_device_monitor_get ();
   g_signal_connect_swapped (launcher->device_monitor, "device-added", G_CALLBACK (thunar_launcher_update), launcher);
   g_signal_connect_swapped (launcher->device_monitor, "device-removed", G_CALLBACK (thunar_launcher_update), launcher);
+
+  /* update launcher actions when any monitored file changes */
+  launcher->file_monitor = thunar_file_monitor_get_default ();
+  g_signal_connect_swapped (launcher->file_monitor, "file-changed", G_CALLBACK (thunar_launcher_update), launcher);
 }
 
 
@@ -336,6 +343,10 @@ thunar_launcher_finalize (GObject *object)
   /* release the reference on the sendto model */
   g_object_unref (launcher->sendto_model);
 
+  /* disconnect from the file monitor */
+  g_signal_handlers_disconnect_by_func (launcher->file_monitor, thunar_launcher_update, launcher);
+  g_object_unref (launcher->file_monitor);
+
   (*G_OBJECT_CLASS (thunar_launcher_parent_class)->finalize) (object);
 }
 
@@ -1761,6 +1772,7 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
           /* allocate a new action for the device */
           action = gtk_action_new (name, device_name, tooltip, NULL);
           g_object_set_qdata_full (G_OBJECT (action), thunar_launcher_handler_quark, lp->data, g_object_unref);
+          g_object_set_data (G_OBJECT (lp->data), "skip-app-info-update", GUINT_TO_POINTER (1));
           g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_launcher_action_sendto_device), launcher);
           gtk_action_group_add_action (launcher->action_group, action);
           gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id,
@@ -1818,6 +1830,7 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
               action = gtk_action_new (name, label, tooltip, NULL);
               gtk_action_set_gicon (action, g_app_info_get_icon (lp->data));
               g_object_set_qdata_full (G_OBJECT (action), thunar_launcher_handler_quark, lp->data, g_object_unref);
+              g_object_set_data (G_OBJECT (lp->data), "skip-app-info-update", GUINT_TO_POINTER (1));
               g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_launcher_action_open), launcher);
               gtk_action_group_add_action (launcher->action_group, action);
               gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id,
diff --git a/thunar/thunar-list-model.c b/thunar/thunar-list-model.c
index bc82f85c..201862c2 100644
--- a/thunar/thunar-list-model.c
+++ b/thunar/thunar-list-model.c
@@ -1741,7 +1741,7 @@ thunar_list_model_set_case_sensitive (ThunarListModel *store,
       /* emit a "changed" signal for each row, so the display is
          reloaded with the new case-sensitive setting */
       gtk_tree_model_foreach (GTK_TREE_MODEL (store),
-                              (GtkTreeModelForeachFunc) gtk_tree_model_row_changed,
+                              (GtkTreeModelForeachFunc) (void (*)(void)) gtk_tree_model_row_changed,
                               NULL);
     }
 }
@@ -1789,7 +1789,9 @@ thunar_list_model_set_date_style (ThunarListModel *store,
       g_object_notify_by_pspec (G_OBJECT (store), list_model_props[PROP_DATE_STYLE]);
 
       /* emit a "changed" signal for each row, so the display is reloaded with the new date style */
-      gtk_tree_model_foreach (GTK_TREE_MODEL (store), (GtkTreeModelForeachFunc) gtk_tree_model_row_changed, NULL);
+      gtk_tree_model_foreach (GTK_TREE_MODEL (store),
+                              (GtkTreeModelForeachFunc) (void (*)(void)) gtk_tree_model_row_changed,
+                              NULL);
     }
 }
 
@@ -1834,7 +1836,9 @@ thunar_list_model_set_date_custom_style (ThunarListModel *store,
       g_object_notify_by_pspec (G_OBJECT (store), list_model_props[PROP_DATE_CUSTOM_STYLE]);
 
       /* emit a "changed" signal for each row, so the display is reloaded with the new date style */
-      gtk_tree_model_foreach (GTK_TREE_MODEL (store), (GtkTreeModelForeachFunc) gtk_tree_model_row_changed, NULL);
+      gtk_tree_model_foreach (GTK_TREE_MODEL (store),
+                              (GtkTreeModelForeachFunc) (void (*)(void)) gtk_tree_model_row_changed,
+                              NULL);
     }
 }
 
@@ -1996,7 +2000,7 @@ thunar_list_model_set_folders_first (ThunarListModel *store,
   /* emit a "changed" signal for each row, so the display is
      reloaded with the new folders first setting */
   gtk_tree_model_foreach (GTK_TREE_MODEL (store),
-                          (GtkTreeModelForeachFunc) gtk_tree_model_row_changed,
+                          (GtkTreeModelForeachFunc) (void (*)(void)) gtk_tree_model_row_changed,
                           NULL);
 }
 
@@ -2155,7 +2159,7 @@ thunar_list_model_set_file_size_binary (ThunarListModel *store,
       /* emit a "changed" signal for each row, so the display is
          reloaded with the new binary file size setting */
       gtk_tree_model_foreach (GTK_TREE_MODEL (store),
-                              (GtkTreeModelForeachFunc) gtk_tree_model_row_changed,
+                              (GtkTreeModelForeachFunc) (void (*)(void)) gtk_tree_model_row_changed,
                               NULL);
     }
 }
diff --git a/thunar/thunar-location-button.c b/thunar/thunar-location-button.c
index 30ea56e4..126ba936 100644
--- a/thunar/thunar-location-button.c
+++ b/thunar/thunar-location-button.c
@@ -444,6 +444,10 @@ thunar_location_button_file_changed (ThunarLocationButton *location_button,
       dnd_icon_name = thunar_file_get_icon_name (file, location_button->file_icon_state, icon_theme);
       gtk_drag_source_set_icon_name (GTK_WIDGET (location_button), dnd_icon_name);
     }
+
+  /* recalculate the required size in case the filename changed */
+  gtk_widget_set_size_request (GTK_WIDGET (location_button->label), -1, -1);
+
 }
 
 
@@ -559,7 +563,7 @@ thunar_location_button_button_release_event (GtkWidget            *button,
           if (open_in_tab)
             {
               /* open in tab */
-              g_signal_emit_by_name (G_OBJECT (button), "location-button-clicked", 0, TRUE);
+              g_signal_emit_by_name (G_OBJECT (button), "location-button-clicked", TRUE);
             }
           else
             {
diff --git a/thunar/thunar-location-buttons.c b/thunar/thunar-location-buttons.c
index 872e4568..eed9dffa 100644
--- a/thunar/thunar-location-buttons.c
+++ b/thunar/thunar-location-buttons.c
@@ -1280,7 +1280,7 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
       /* setup the "Empty Trash" action */
       action = gtk_action_group_get_action (buttons->action_group, "location-buttons-empty-trash");
       gtk_action_set_visible (action, (thunar_file_is_root (file) && thunar_file_is_trashed (file)));
-      gtk_action_set_sensitive (action, (thunar_file_get_size (file) > 0));
+      gtk_action_set_sensitive (action, (thunar_file_get_item_count (file) > 0));
       gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_action_create_menu_item (action));
 G_GNUC_END_IGNORE_DEPRECATIONS
 
diff --git a/thunar/thunar-location-entry.c b/thunar/thunar-location-entry.c
index fff18e1e..bd9406ea 100644
--- a/thunar/thunar-location-entry.c
+++ b/thunar/thunar-location-entry.c
@@ -62,6 +62,9 @@ static void        thunar_location_entry_set_current_directory    (ThunarNavigat
                                                                    ThunarFile               *current_directory);
 static void        thunar_location_entry_activate                 (GtkWidget                *path_entry,
                                                                    ThunarLocationEntry      *location_entry);
+static gboolean    thunar_location_entry_button_press_event       (GtkWidget                *path_entry,
+                                                                   GdkEventButton           *event,
+                                                                   ThunarLocationEntry      *location_entry);
 static gboolean    thunar_location_entry_reset                    (ThunarLocationEntry      *location_entry);
 static void        thunar_location_entry_reload                   (GtkEntry                 *entry,
                                                                    GtkEntryIconPosition      icon_pos,
@@ -89,6 +92,8 @@ struct _ThunarLocationEntry
 
   ThunarFile   *current_directory;
   GtkWidget    *path_entry;
+
+  gboolean      right_click_occurred;
 };
 
 
@@ -198,6 +203,11 @@ thunar_location_entry_init (ThunarLocationEntry *location_entry)
 
   /* make sure the edit-done signal is emitted upon moving the focus somewhere else */
   g_signal_connect_swapped (location_entry->path_entry, "focus-out-event", G_CALLBACK (thunar_location_entry_emit_edit_done), location_entry);
+
+  /* ...except if it is grabbed by the context menu */
+  location_entry->right_click_occurred = FALSE;
+  g_signal_connect (G_OBJECT (location_entry->path_entry), "button-press-event",
+                    G_CALLBACK (thunar_location_entry_button_press_event), location_entry);
 }
 
 
@@ -410,6 +420,24 @@ thunar_location_entry_activate (GtkWidget           *path_entry,
 
 
 
+static gboolean
+thunar_location_entry_button_press_event (GtkWidget           *path_entry,
+                                          GdkEventButton      *event,
+                                          ThunarLocationEntry *location_entry)
+{
+  _thunar_return_val_if_fail (THUNAR_IS_LOCATION_ENTRY (location_entry), FALSE);
+
+  /* check if the context menu was triggered */
+  if (event->type == GDK_BUTTON_PRESS && event->button == 3)
+    {
+      location_entry->right_click_occurred = TRUE;
+    }
+
+  return FALSE;
+}
+
+
+
 static gboolean
 thunar_location_entry_reset (ThunarLocationEntry *location_entry)
 {
@@ -445,7 +473,13 @@ thunar_location_entry_reload (GtkEntry            *entry,
 static void
 thunar_location_entry_emit_edit_done (ThunarLocationEntry *entry)
 {
-    g_signal_emit_by_name (entry, "edit-done");
+  /* do not emit signal if the context menu was opened */
+  if (entry->right_click_occurred == FALSE)
+    {
+      g_signal_emit_by_name (entry, "edit-done");
+    }
+
+  entry->right_click_occurred = FALSE;
 }
 
 
diff --git a/thunar/thunar-menu-util.c b/thunar/thunar-menu-util.c
index ca32ee4c..5caacc41 100644
--- a/thunar/thunar-menu-util.c
+++ b/thunar/thunar-menu-util.c
@@ -72,7 +72,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
   g_signal_connect_data (action, "activate",
                          G_CALLBACK (extension_action_callback),
                          g_object_ref (item),
-                         (GClosureNotify) g_object_unref, 0);
+                         (GClosureNotify) (void (*)(void)) g_object_unref, 0);
 
   g_free (name);
   g_free (label);
diff --git a/thunar/thunar-misc-jobs.c b/thunar/thunar-misc-jobs.c
deleted file mode 100644
index f131d8d1..00000000
--- a/thunar/thunar-misc-jobs.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/*-
- * Copyright (c) 2009-2011 Jannis Pohlmann <jannis@xfce.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gio/gio.h>
-
-#include <thunar/thunar-io-scan-directory.h>
-#include <thunar/thunar-job.h>
-#include <thunar/thunar-misc-jobs.h>
-#include <thunar/thunar-private.h>
-#include <thunar/thunar-simple-job.h>
-
-
-
-static gboolean
-_thunar_misc_jobs_load_templates (ThunarJob  *job,
-                                  GArray     *param_values,
-                                  GError    **error)
-{
-  GtkWidget   *menu;
-  GFile       *home_dir;
-  GFile       *templates_dir;
-  GList       *files = NULL;
-  const gchar *path;
-
-  _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
-  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-  _thunar_return_val_if_fail (param_values != NULL && param_values->len == 1, FALSE);
-
-  menu = g_value_get_object (&g_array_index (param_values, GValue, 0));
-  g_object_set_data (G_OBJECT (job), "menu", menu);
-
-  home_dir = thunar_g_file_new_for_home ();
-  path = g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES);
-  if (G_LIKELY (path != NULL))
-    templates_dir = g_file_new_for_path (path);
-  else
-    templates_dir = g_file_resolve_relative_path (home_dir, "Templates");
-
-  if (G_LIKELY (!g_file_equal (templates_dir, home_dir)))
-    {
-      /* load the ThunarFiles */
-      files = thunar_io_scan_directory (job, templates_dir,
-                                        G_FILE_QUERY_INFO_NONE, /* symlink ok */
-                                        TRUE, FALSE, TRUE, NULL);
-    }
-
-  g_object_unref (templates_dir);
-  g_object_unref (home_dir);
-
-  if (files == NULL || exo_job_is_cancelled (EXO_JOB (job)))
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
-                   _("No templates installed"));
-
-      return FALSE;
-    }
-  else
-    {
-      if (!thunar_job_files_ready (job, files))
-        thunar_g_file_list_free (files);
-
-      return TRUE;
-    }
-}
-
-
-
-ThunarJob *
-thunar_misc_jobs_load_template_files (GtkWidget *menu)
-{
-  return thunar_simple_job_launch (_thunar_misc_jobs_load_templates, 1,
-                                   GTK_TYPE_MENU, menu);
-}
diff --git a/thunar/thunar-misc-jobs.h b/thunar/thunar-misc-jobs.h
deleted file mode 100644
index 21483af0..00000000
--- a/thunar/thunar-misc-jobs.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/*-
- * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __THUNAR_MISC_JOBS_H__
-#define __THUNAR_MISC_JOBS_H__
-
-#include <thunar/thunar-job.h>
-
-G_BEGIN_DECLS
-
-ThunarJob *thunar_misc_jobs_load_template_files (GtkWidget *menu);
-
-G_END_DECLS
-
-#endif /* !__THUNAR_MISC_JOBS_H__ */
diff --git a/thunar/thunar-navigator.c b/thunar/thunar-navigator.c
index ff3e7617..ad5e8686 100644
--- a/thunar/thunar-navigator.c
+++ b/thunar/thunar-navigator.c
@@ -57,7 +57,7 @@ thunar_navigator_get_type (void)
         sizeof (ThunarNavigatorIface),
         (GBaseInitFunc) thunar_navigator_base_init,
         NULL,
-        (GClassInitFunc) thunar_navigator_class_init,
+        (GClassInitFunc) (void (*)(void)) thunar_navigator_class_init,
         NULL,
         NULL,
         0,
diff --git a/thunar/thunar-pango-extensions.c b/thunar/thunar-pango-extensions.c
index 545b3a96..d42f83ba 100644
--- a/thunar/thunar-pango-extensions.c
+++ b/thunar/thunar-pango-extensions.c
@@ -118,6 +118,31 @@ thunar_pango_attr_list_bold (void)
 
 
 
+/**
+ * thunar_pango_attr_disable_hyphens:
+ *
+ * Returns a #PangoAttrList for not inserting hyphens at intra-word line breaks.
+ * The returned list is owned by the callee and must
+ * not be freed or modified by the caller.
+ *
+ * Return value: a #PangoAttrList for not inserting hyphens at intra-word line
+ *               breaks.
+ **/
+#if PANGO_VERSION_CHECK (1, 44, 0)
+PangoAttrList*
+thunar_pango_attr_disable_hyphens (void)
+{
+  static PangoAttrList *attr_list = NULL;
+
+  if (G_UNLIKELY (attr_list == NULL))
+    attr_list = thunar_pango_attr_list_wrap (pango_attr_insert_hyphens_new (FALSE), NULL);
+
+  return attr_list;
+}
+#endif
+
+
+
 /**
  * thunar_pango_attr_list_italic:
  *
diff --git a/thunar/thunar-pango-extensions.h b/thunar/thunar-pango-extensions.h
index a9d2c1cd..c86966e1 100644
--- a/thunar/thunar-pango-extensions.h
+++ b/thunar/thunar-pango-extensions.h
@@ -27,6 +27,9 @@ G_BEGIN_DECLS;
 PangoAttrList *thunar_pango_attr_list_big               (void) G_GNUC_CONST;
 PangoAttrList *thunar_pango_attr_list_big_bold          (void) G_GNUC_CONST;
 PangoAttrList *thunar_pango_attr_list_bold              (void) G_GNUC_CONST;
+#if PANGO_VERSION_CHECK (1, 44, 0)
+PangoAttrList *thunar_pango_attr_disable_hyphens        (void) G_GNUC_CONST;
+#endif
 PangoAttrList *thunar_pango_attr_list_italic            (void) G_GNUC_CONST;
 PangoAttrList *thunar_pango_attr_list_small_italic      (void) G_GNUC_CONST;
 PangoAttrList *thunar_pango_attr_list_small             (void) G_GNUC_CONST;
diff --git a/thunar/thunar-path-entry.c b/thunar/thunar-path-entry.c
index 049e0ed2..76b5b64c 100644
--- a/thunar/thunar-path-entry.c
+++ b/thunar/thunar-path-entry.c
@@ -614,7 +614,7 @@ thunar_path_entry_changed (GtkEditable *editable)
 
       /* set the new folder for the completion model, but disconnect the model from the
        * completion first, because GtkEntryCompletion has become very slow recently when
-       * updating the model being used (http://bugzilla.xfce.org/show_bug.cgi?id=1681).
+       * updating the model being used (https://bugzilla.xfce.org/show_bug.cgi?id=1681).
        */
       model = gtk_entry_completion_get_model (completion);
       g_object_ref (G_OBJECT (model));
@@ -893,22 +893,29 @@ thunar_path_entry_match_func (GtkEntryCompletion *completion,
                               GtkTreeIter        *iter,
                               gpointer            user_data)
 {
-  GtkTreeModel *model;
-  const gchar  *last_slash;
-  ThunarFile   *file;
-  gboolean      matched;
-  gchar        *text_normalized;
-  gchar        *name_normalized;
-  gchar        *name;
+  GtkTreeModel    *model;
+  ThunarPathEntry *path_entry;
+  const gchar     *last_slash;
+  ThunarFile      *file;
+  gboolean         matched;
+  gchar           *text_normalized;
+  gchar           *name_normalized;
+  gchar           *name;
 
   /* determine the model from the completion */
   model = gtk_entry_completion_get_model (completion);
 
   /* leave if the model is null, we do this in thunar_path_entry_changed() to speed
-   * things up, but that causes http://bugzilla.xfce.org/show_bug.cgi?id=4847. */
+   * things up, but that causes https://bugzilla.xfce.org/show_bug.cgi?id=4847. */
   if (G_UNLIKELY (model == NULL))
     return FALSE;
 
+  /* leave if the auto completion highlight was not cleared yet, to prevent
+   * https://bugzilla.xfce.org/show_bug.cgi?id=16267. */
+  path_entry = THUNAR_PATH_ENTRY (user_data);
+  if (G_UNLIKELY (path_entry->has_completion))
+    return FALSE;
+
   /* determine the current text (UTF-8 normalized) */
   text_normalized = g_utf8_normalize (gtk_entry_get_text (GTK_ENTRY (user_data)), -1, G_NORMALIZE_ALL);
 
diff --git a/thunar/thunar-permissions-chooser.c b/thunar/thunar-permissions-chooser.c
index e02e2fca..b4534313 100644
--- a/thunar/thunar-permissions-chooser.c
+++ b/thunar/thunar-permissions-chooser.c
@@ -939,7 +939,7 @@ thunar_permissions_chooser_file_changed (ThunarPermissionsChooser *chooser)
       if (G_LIKELY (user != NULL))
         {
           groups = g_list_copy (thunar_user_get_groups (user));
-          g_list_foreach (groups, (GFunc) g_object_ref, NULL);
+          g_list_foreach (groups, (GFunc) (void (*)(void)) g_object_ref, NULL);
         }
     }
 
@@ -1009,14 +1009,9 @@ thunar_permissions_chooser_file_changed (ThunarPermissionsChooser *chooser)
       g_object_unref (G_OBJECT (access_store));
     }
 
-  /* update the program setting based on the mode (only visible for regular files, allowed for execution) */
+  /* update the program setting based on the mode (only visible for regular files) */
   g_signal_handlers_block_by_func (G_OBJECT (chooser->program_button), thunar_permissions_chooser_program_toggled, chooser);
-  g_object_set (G_OBJECT (chooser->program_button), "visible", thunar_file_is_regular (file)
-      && (thunarx_file_info_has_mime_type (THUNARX_FILE_INFO (file), "application/x-executable")
-       || thunarx_file_info_has_mime_type (THUNARX_FILE_INFO (file), "application/x-shellscript")
-       || thunarx_file_info_has_mime_type (THUNARX_FILE_INFO (file), "application/x-desktop")
-       || thunarx_file_info_has_mime_type (THUNARX_FILE_INFO (file), "application/x-ms-dos-executable")
-       || thunarx_file_info_has_mime_type (THUNARX_FILE_INFO (file), "application/x-msi")), NULL);
+  g_object_set (G_OBJECT (chooser->program_button), "visible", thunar_file_is_regular (file), NULL);
   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chooser->program_button), (mode & 0111) != 0);
   g_signal_handlers_unblock_by_func (G_OBJECT (chooser->program_button), thunar_permissions_chooser_program_toggled, chooser);
 
diff --git a/thunar/thunar-preferences-dialog.c b/thunar/thunar-preferences-dialog.c
index 101c5fa2..cfaf7cc6 100644
--- a/thunar/thunar-preferences-dialog.c
+++ b/thunar/thunar-preferences-dialog.c
@@ -229,6 +229,7 @@ thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog)
   GtkWidget      *button;
   GtkWidget      *combo;
   GtkWidget      *entry;
+  GtkWidget      *image;
   GtkWidget      *frame;
   GtkWidget      *label;
   GtkWidget      *range;
@@ -248,11 +249,31 @@ thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog)
   gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
   gtk_window_set_title (GTK_WINDOW (dialog), _("File Manager Preferences"));
 
-  /* add "Help" and "Close" buttons */
-  gtk_dialog_add_buttons (GTK_DIALOG (dialog),
-                          _("_Close"), GTK_RESPONSE_CLOSE,
-                          _("_Help"), GTK_RESPONSE_HELP,
-                          NULL);
+#if LIBXFCE4UI_CHECK_VERSION (4, 15, 1)
+  xfce_titled_dialog_create_action_area (XFCE_TITLED_DIALOG (dialog));
+#endif
+
+  /* add the "Close" button */
+  button = gtk_button_new_with_mnemonic (_("_Close"));
+  image = gtk_image_new_from_icon_name ("window-close", GTK_ICON_SIZE_BUTTON);
+  gtk_button_set_image (GTK_BUTTON (button), image);
+#if LIBXFCE4UI_CHECK_VERSION (4, 15, 1)
+  xfce_titled_dialog_add_action_widget (XFCE_TITLED_DIALOG (dialog), button, GTK_RESPONSE_CLOSE);
+#else
+  gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_CLOSE);
+#endif
+  gtk_widget_show (button);
+
+  /* add the "Help" button */
+  button = gtk_button_new_with_mnemonic (_("_Help"));
+  image = gtk_image_new_from_icon_name ("help-browser", GTK_ICON_SIZE_BUTTON);
+  gtk_button_set_image (GTK_BUTTON (button), image);
+#if LIBXFCE4UI_CHECK_VERSION (4, 15, 1)
+  xfce_titled_dialog_add_action_widget (XFCE_TITLED_DIALOG (dialog), button, GTK_RESPONSE_HELP);
+#else
+  gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_HELP);
+#endif
+  gtk_widget_show (button);
 
   notebook = gtk_notebook_new ();
   gtk_container_set_border_width (GTK_CONTAINER (notebook), 6);
@@ -711,8 +732,8 @@ thunar_preferences_dialog_init (ThunarPreferencesDialog *dialog)
 
   combo = gtk_combo_box_text_new ();
   gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("Ask every time"));
-  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("Apply to Folder Only"));
   gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("Apply to Folder and Contents"));
+  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), _("Apply to Folder Only"));
   exo_mutual_binding_new (G_OBJECT (dialog->preferences), "misc-recursive-permissions", G_OBJECT (combo), "active");
   gtk_widget_set_hexpand (combo, TRUE);
   gtk_grid_attach (GTK_GRID (grid), combo, 0, 1, 1, 1);
diff --git a/thunar/thunar-progress-dialog.c b/thunar/thunar-progress-dialog.c
index 7d227c21..f4de6097 100644
--- a/thunar/thunar-progress-dialog.c
+++ b/thunar/thunar-progress-dialog.c
@@ -368,6 +368,7 @@ thunar_progress_dialog_add_job (ThunarProgressDialog *dialog,
       dialog->scrollwin = gtk_scrolled_window_new (NULL, NULL);
       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (dialog->scrollwin),
                                       GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+      gtk_widget_set_vexpand (dialog->scrollwin, TRUE);
       gtk_container_add (GTK_CONTAINER (dialog->vbox), dialog->scrollwin);
       gtk_widget_show (dialog->scrollwin);
 
diff --git a/thunar/thunar-properties-dialog.c b/thunar/thunar-properties-dialog.c
index e612a926..848eb564 100644
--- a/thunar/thunar-properties-dialog.c
+++ b/thunar/thunar-properties-dialog.c
@@ -704,7 +704,7 @@ static gboolean
 thunar_properties_dialog_reload (ThunarPropertiesDialog *dialog)
 {
   /* reload the active files */
-  g_list_foreach (dialog->files, (GFunc) thunar_file_reload, NULL);
+  g_list_foreach (dialog->files, (GFunc) (void (*)(void)) thunar_file_reload, NULL);
 
   return dialog->files != NULL;
 }
diff --git a/thunar/thunar-renamer-progress.c b/thunar/thunar-renamer-progress.c
index ef628b3e..57230000 100644
--- a/thunar/thunar-renamer-progress.c
+++ b/thunar/thunar-renamer-progress.c
@@ -361,6 +361,7 @@ thunar_renamer_progress_run (ThunarRenamerProgress *renamer_progress,
   /* make sure to release the list of completed items first */
   thunar_renamer_pair_list_free (renamer_progress->pairs_done);
   renamer_progress->pairs_done = NULL;
+  renamer_progress->n_pairs_done = 0;
 
   /* set the pairs on the todo list */
   thunar_renamer_pair_list_free (renamer_progress->pairs_todo);
diff --git a/thunar/thunar-sendto-model.c b/thunar/thunar-sendto-model.c
index 42253864..35418582 100644
--- a/thunar/thunar-sendto-model.c
+++ b/thunar/thunar-sendto-model.c
@@ -154,7 +154,7 @@ thunar_sendto_model_load (ThunarSendtoModel *sendto_model)
               /* add to our handler list, sorted by their desktop-ids (reverse order) */
               sendto_model->handlers = g_list_insert_sorted (sendto_model->handlers,
                                                              G_APP_INFO (app_info),
-                                                             (GCompareFunc) g_app_info_compare);
+                                                             (GCompareFunc) (void (*)(void)) g_app_info_compare);
 
               /* attach the mime-types to the object */
               mime_types = g_key_file_get_string_list (key_file,
diff --git a/thunar/thunar-session-client.c b/thunar/thunar-session-client.c
index 60728b54..40fd04c8 100644
--- a/thunar/thunar-session-client.c
+++ b/thunar/thunar-session-client.c
@@ -256,7 +256,7 @@ thunar_session_client_connect (ThunarSessionClient *session_client,
   prop_priority.type = SmCARD8;
   prop_priority.num_vals = G_N_ELEMENTS (value_priority);
   prop_priority.vals = &value_priority[0];
-  value_priority[0].value = "\30";
+  value_priority[0].value = "\36"; /* this is octal, 30 in decimal */
   value_priority[0].length = 1;
 
   /* setup the properties list */
diff --git a/thunar/thunar-settings.desktop.in b/thunar/thunar-settings.desktop.in
index 18e11d4d..9d7c2fae 100644
--- a/thunar/thunar-settings.desktop.in
+++ b/thunar/thunar-settings.desktop.in
@@ -1,6 +1,6 @@
 [Desktop Entry]
 Version=1.0
-_Name=File Manager
+_Name=File Manager Settings
 _Comment=Configure the Thunar file manager
 Exec=thunar-settings
 Icon=system-file-manager
diff --git a/thunar/thunar-shortcuts-model.c b/thunar/thunar-shortcuts-model.c
index 0c9b5133..d5e92df2 100644
--- a/thunar/thunar-shortcuts-model.c
+++ b/thunar/thunar-shortcuts-model.c
@@ -318,7 +318,7 @@ thunar_shortcuts_model_finalize (GObject *object)
     g_source_remove (model->bookmarks_idle_id);
 
   /* free all shortcuts */
-  g_list_foreach (model->shortcuts, (GFunc) thunar_shortcut_free, model);
+  g_list_foreach (model->shortcuts, (GFunc) (void (*)(void)) thunar_shortcut_free, model);
   g_list_free (model->shortcuts);
 
   /* disconnect from the preferences */
@@ -495,6 +495,9 @@ thunar_shortcuts_model_get_column_type (GtkTreeModel *tree_model,
 
     case THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY_PULSE:
       return G_TYPE_UINT;
+
+    case THUNAR_SHORTCUTS_MODEL_COLUMN_HIDDEN:
+      return G_TYPE_BOOLEAN;
     }
 
   _thunar_assert_not_reached ();
@@ -711,6 +714,11 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
       g_value_set_uint (value, shortcut->busy_pulse);
       break;
 
+    case THUNAR_SHORTCUTS_MODEL_COLUMN_HIDDEN:
+      g_value_init (value, G_TYPE_BOOLEAN);
+      g_value_set_boolean (value, FALSE);
+      break;
+
     default:
       _thunar_assert_not_reached ();
     }
diff --git a/thunar/thunar-shortcuts-model.h b/thunar/thunar-shortcuts-model.h
index cb87a1f7..677e9b43 100644
--- a/thunar/thunar-shortcuts-model.h
+++ b/thunar/thunar-shortcuts-model.h
@@ -52,6 +52,7 @@ typedef enum
   THUNAR_SHORTCUTS_MODEL_COLUMN_GROUP,
   THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY,
   THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY_PULSE,
+  THUNAR_SHORTCUTS_MODEL_COLUMN_HIDDEN,
   THUNAR_SHORTCUTS_MODEL_N_COLUMNS,
 } ThunarShortcutsModelColumn;
 
diff --git a/thunar/thunar-shortcuts-pane.c b/thunar/thunar-shortcuts-pane.c
index 98b5d6eb..2cc26a20 100644
--- a/thunar/thunar-shortcuts-pane.c
+++ b/thunar/thunar-shortcuts-pane.c
@@ -66,6 +66,8 @@ static void          thunar_shortcuts_pane_set_ui_manager        (ThunarComponen
                                                                   GtkUIManager             *ui_manager);
 static void          thunar_shortcuts_pane_action_shortcuts_add  (GtkAction                *action,
                                                                   ThunarShortcutsPane      *shortcuts_pane);
+static void          thunar_shortcuts_pane_show_shortcuts_view_padding (GtkWidget          *widget);
+static void          thunar_shortcuts_pane_hide_shortcuts_view_padding (GtkWidget          *widget);
 
 
 
@@ -94,7 +96,7 @@ struct _ThunarShortcutsPane
 
 static const GtkActionEntry action_entries[] =
 {
-  { "sendto-shortcuts", "stock_thunar-shortcuts", "", NULL, NULL, G_CALLBACK (thunar_shortcuts_pane_action_shortcuts_add), },
+  { "sendto-shortcuts", "bookmark-new", "", NULL, NULL, G_CALLBACK (thunar_shortcuts_pane_action_shortcuts_add), },
 };
 
 
@@ -162,6 +164,8 @@ thunar_shortcuts_pane_side_pane_init (ThunarSidePaneIface *iface)
 static void
 thunar_shortcuts_pane_init (ThunarShortcutsPane *shortcuts_pane)
 {
+  GtkWidget *vscrollbar;
+
   /* setup the action group for the shortcuts actions */
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   shortcuts_pane->action_group = gtk_action_group_new ("ThunarShortcutsPane");
@@ -180,6 +184,14 @@ G_GNUC_END_IGNORE_DEPRECATIONS
   gtk_container_add (GTK_CONTAINER (shortcuts_pane), shortcuts_pane->view);
   gtk_widget_show (shortcuts_pane->view);
 
+  vscrollbar = gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (shortcuts_pane));
+  g_signal_connect_swapped (G_OBJECT (vscrollbar), "map",
+                            G_CALLBACK (thunar_shortcuts_pane_show_shortcuts_view_padding),
+                            shortcuts_pane->view);
+  g_signal_connect_swapped (G_OBJECT (vscrollbar), "unmap",
+                            G_CALLBACK (thunar_shortcuts_pane_hide_shortcuts_view_padding),
+                            shortcuts_pane->view);
+
   /* add widget to css class */
   gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (shortcuts_pane)), "shortcuts-pane");
 
@@ -508,3 +520,19 @@ G_GNUC_END_IGNORE_DEPRECATIONS
       thunar_g_file_list_free (lp);
     }
 }
+
+
+
+static void
+thunar_shortcuts_pane_show_shortcuts_view_padding (GtkWidget *widget)
+{
+  thunar_shortcuts_view_toggle_padding (THUNAR_SHORTCUTS_VIEW (widget), TRUE);
+}
+
+
+
+static void
+thunar_shortcuts_pane_hide_shortcuts_view_padding (GtkWidget *widget)
+{
+  thunar_shortcuts_view_toggle_padding (THUNAR_SHORTCUTS_VIEW (widget), FALSE);
+}
diff --git a/thunar/thunar-shortcuts-view.c b/thunar/thunar-shortcuts-view.c
index 8e3b0e86..281e44e2 100644
--- a/thunar/thunar-shortcuts-view.c
+++ b/thunar/thunar-shortcuts-view.c
@@ -168,6 +168,9 @@ struct _ThunarShortcutsView
 
   ThunarPreferences      *preferences;
   GtkCellRenderer        *icon_renderer;
+  GtkCellRenderer        *padding_renderer;
+  GtkTreeViewColumn      *column;
+  gboolean                padding_enabled;
 
   ThunarxProviderFactory *provider_factory;
 
@@ -269,7 +272,7 @@ thunar_shortcuts_view_class_init (ThunarShortcutsViewClass *klass)
 static void
 thunar_shortcuts_view_init (ThunarShortcutsView *view)
 {
-  GtkTreeViewColumn *column, *column_eject;
+  GtkTreeViewColumn *column;
   GtkCellRenderer   *renderer;
   GtkTreeSelection  *selection;
 
@@ -288,18 +291,14 @@ thunar_shortcuts_view_init (ThunarShortcutsView *view)
   g_signal_connect_swapped (G_OBJECT (view->preferences), "notify::shortcuts-icon-emblems", G_CALLBACK (gtk_widget_queue_draw), view);
 
   /* allocate a single column for our renderers */
-  column = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN,
+  column = view->column = g_object_new (GTK_TYPE_TREE_VIEW_COLUMN,
                          "reorderable", FALSE,
                          "resizable", FALSE,
                          "expand", TRUE,
-                         "sizing", GTK_TREE_VIEW_COLUMN_AUTOSIZE,
                          "spacing", 2,
                          NULL);
   gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
 
-  column_eject = gtk_tree_view_column_new ();
-  gtk_tree_view_append_column (GTK_TREE_VIEW (view), column_eject);
-
   /* queue a resize on the column whenever the icon size is changed */
   view->queue_resize_signal_id = g_signal_connect_swapped (G_OBJECT (view->preferences), "notify::shortcuts-icon-size",
                                                            G_CALLBACK (gtk_tree_view_column_queue_resize), column);
@@ -311,7 +310,7 @@ thunar_shortcuts_view_init (ThunarShortcutsView *view)
                            "ypad", 4,
                            "ellipsize", PANGO_ELLIPSIZE_END,
                            NULL);
-  gtk_tree_view_column_pack_start (column, renderer, FALSE);
+  gtk_tree_view_column_pack_end (column, renderer, FALSE);
   gtk_tree_view_column_set_attributes (column, renderer,
                                        "text", THUNAR_SHORTCUTS_MODEL_COLUMN_NAME,
                                        "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_IS_HEADER,
@@ -354,8 +353,8 @@ thunar_shortcuts_view_init (ThunarShortcutsView *view)
 
   /* spinner to indicate (un)mount/eject delay */
   renderer = gtk_cell_renderer_spinner_new ();
-  gtk_tree_view_column_pack_start (column_eject, renderer, FALSE);
-  gtk_tree_view_column_set_attributes (column_eject, renderer,
+  gtk_tree_view_column_pack_start (column, renderer, FALSE);
+  gtk_tree_view_column_set_attributes (column, renderer,
                                        "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY,
                                        "active", THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY,
                                        "pulse", THUNAR_SHORTCUTS_MODEL_COLUMN_BUSY_PULSE,
@@ -364,8 +363,17 @@ thunar_shortcuts_view_init (ThunarShortcutsView *view)
   /* allocate icon renderer for the eject symbol */
   renderer = gtk_cell_renderer_pixbuf_new ();
   g_object_set (renderer, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, "icon-name", "media-eject", NULL);
-  gtk_tree_view_column_pack_start (column_eject, renderer, FALSE);
-  gtk_tree_view_column_set_attributes (column_eject, renderer,
+  gtk_tree_view_column_pack_start (column, renderer, FALSE);
+  gtk_tree_view_column_set_attributes (column, renderer,
+                                       "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_CAN_EJECT,
+                                       NULL);
+
+  /* padding for the eject symbol so it's not covered by scroll bar */
+  view->padding_enabled = FALSE;
+  view->padding_renderer = gtk_cell_renderer_text_new ();
+  g_object_set (G_OBJECT (view->padding_renderer), "xpad", 6, NULL);
+  gtk_tree_view_column_pack_start (column, view->padding_renderer, FALSE);
+  gtk_tree_view_column_set_attributes (column, view->padding_renderer,
                                        "visible", THUNAR_SHORTCUTS_MODEL_COLUMN_CAN_EJECT,
                                        NULL);
 
@@ -418,7 +426,7 @@ thunar_shortcuts_view_button_press_event (GtkWidget      *widget,
   GtkTreeIter          iter;
   gboolean             result;
   gboolean             can_eject;
-  gint                 icon_width, icon_height, column_width;
+  gint                 icon_width, column_width;
 
   /* reset the pressed button state */
   view->pressed_button = -1;
@@ -453,8 +461,8 @@ thunar_shortcuts_view_button_press_event (GtkWidget      *widget,
         {
           /* check if we clicked the eject button area */
           column_width = gtk_tree_view_column_get_width (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0));
-          gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
-          if (event->button == 1 && event->x > column_width)
+          gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, NULL);
+          if (event->button == 1 && event->x >= column_width - icon_width - (view->padding_enabled ? 16 : 3))
             {
               /* check if that shortcut actually has an eject button */
               model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
@@ -837,6 +845,11 @@ thunar_shortcuts_view_drag_motion (GtkWidget      *widget,
       gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (view), path, position);
       gtk_tree_path_free (path);
     }
+  else
+    {
+      /* remove highlight */
+      gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (view), NULL, position);
+    }
 
   /* tell Gdk whether we can drop here */
   gdk_drag_status (context, action, timestamp);
@@ -865,7 +878,7 @@ thunar_shortcuts_view_drag_leave (GtkWidget      *widget,
     }
 
   /* schedule a repaint to make sure the special drop icon for the target row
-   * is reset to its default (http://bugzilla.xfce.org/show_bug.cgi?id=2498).
+   * is reset to its default (https://bugzilla.xfce.org/show_bug.cgi?id=2498).
    */
   gtk_widget_queue_draw (widget);
 
@@ -1183,7 +1196,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
         gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
         gtk_widget_show (item);
 
-        image = gtk_image_new_from_icon_name ("stock_thunar-shortcuts", GTK_ICON_SIZE_MENU);
+        image = gtk_image_new_from_icon_name ("bookmark-new", GTK_ICON_SIZE_MENU);
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
 G_GNUC_END_IGNORE_DEPRECATIONS
@@ -1439,6 +1452,8 @@ thunar_shortcuts_view_compute_drop_actions (ThunarShortcutsView     *view,
   GtkTreeIter        iter;
   ThunarFile        *file;
   gint               cell_y;
+  GList             *lp;
+  guint              n;
 
   /* determine the shortcuts model */
   model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
@@ -1481,6 +1496,30 @@ thunar_shortcuts_view_compute_drop_actions (ThunarShortcutsView     *view,
   /* check if we cannot drop into the shortcut */
   if (G_UNLIKELY (actions == 0))
     {
+      /* check if any of the paths is not directory but only up to 100, if
+       * someone drags too many directories it may slowdown or even freeze
+       * Thunar while moving the cursor.
+       */
+      for (lp = view->drop_file_list, n = 0; lp != NULL && n < 100; lp = lp->next, ++n)
+        {
+          GFileInfo *info;
+          gboolean   is_directory;
+
+          info = g_file_query_info (lp->data,
+                                    G_FILE_ATTRIBUTE_STANDARD_TYPE,
+                                    G_FILE_QUERY_INFO_NONE,
+                                    NULL, NULL);
+
+          if (G_UNLIKELY (info == NULL))
+            return 0;
+
+          is_directory = g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY;
+          g_object_unref (info);
+
+          if (!is_directory)
+            return 0;
+        }
+
       /* check the action that should be performed */
       if (gdk_drag_context_get_suggested_action (context) == GDK_ACTION_LINK || (gdk_drag_context_get_actions (context) & GDK_ACTION_LINK) != 0)
         actions = GDK_ACTION_LINK;
@@ -1783,7 +1822,7 @@ thunar_shortcuts_view_open (ThunarShortcutsView *view,
                           THUNAR_SHORTCUTS_MODEL_COLUMN_LOCATION, &location,
                           -1);
 
-      if (G_LIKELY (device != NULL))
+      if (G_LIKELY (THUNAR_IS_DEVICE (device)))
         {
           /* start the spinner */
           child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
@@ -1870,18 +1909,20 @@ thunar_shortcuts_view_create_shortcut (ThunarShortcutsView *view)
     {
       /* determine the device/mount for the shortcut at the given tree iterator */
       gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE, &device, -1);
-      _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
 
-      /* add the mount point to the model */
-      mount_point = thunar_device_get_root (device);
-      if (mount_point != NULL)
+      if (G_LIKELY (THUNAR_IS_DEVICE (device)))
         {
-          shortcuts_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
-          thunar_shortcuts_model_add (THUNAR_SHORTCUTS_MODEL (shortcuts_model), NULL, mount_point);
-          g_object_unref (mount_point);
-        }
+          /* add the mount point to the model */
+          mount_point = thunar_device_get_root (device);
+          if (mount_point != NULL)
+            {
+              shortcuts_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
+              thunar_shortcuts_model_add (THUNAR_SHORTCUTS_MODEL (shortcuts_model), NULL, mount_point);
+              g_object_unref (mount_point);
+            }
 
-      g_object_unref (G_OBJECT (device));
+          g_object_unref (G_OBJECT (device));
+        }
     }
 }
 
@@ -1937,24 +1978,26 @@ thunar_shortcuts_view_eject (ThunarShortcutsView *view)
     {
       /* determine the device/mount for the shortcut at the given tree iterator */
       gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE, &device, -1);
-      _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
 
-      /* prepare a mount operation */
-      mount_operation = thunar_gtk_mount_operation_new (GTK_WIDGET (view));
+      if (G_LIKELY (THUNAR_IS_DEVICE (device)))
+        {
+          /* prepare a mount operation */
+          mount_operation = thunar_gtk_mount_operation_new (GTK_WIDGET (view));
 
-      /* start the spinner */
-      child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
-      thunar_shortcuts_model_set_busy (THUNAR_SHORTCUTS_MODEL (child_model), device, TRUE);
+          /* start the spinner */
+          child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
+          thunar_shortcuts_model_set_busy (THUNAR_SHORTCUTS_MODEL (child_model), device, TRUE);
 
-      /* try to unmount */
-      thunar_device_eject (device,
-                           mount_operation,
-                           NULL,
-                           thunar_shortcuts_view_eject_finish,
-                           g_object_ref (view));
+          /* try to unmount */
+          thunar_device_eject (device,
+                               mount_operation,
+                               NULL,
+                               thunar_shortcuts_view_eject_finish,
+                               g_object_ref (view));
 
-      g_object_unref (G_OBJECT (device));
-      g_object_unref (G_OBJECT (mount_operation));
+          g_object_unref (G_OBJECT (device));
+          g_object_unref (G_OBJECT (mount_operation));
+        }
     }
 }
 
@@ -1965,7 +2008,8 @@ thunar_shortcuts_view_poke_device_mount_finish (ThunarBrowser *browser,
                                                 ThunarDevice  *device,
                                                 ThunarFile    *mount_point,
                                                 GError        *error,
-                                                gpointer       ignored)
+                                                gpointer       ignored,
+                                                gboolean       cancelled)
 {
   gchar        *device_name;
   GtkTreeModel *model;
@@ -2013,7 +2057,7 @@ thunar_shortcuts_view_mount (ThunarShortcutsView *view)
       /* determine the file for the shortcut at the given tree iterator */
       gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE, &device, -1);
 
-      if (G_LIKELY (device != NULL))
+      if (G_LIKELY (THUNAR_IS_DEVICE (device)))
         {
           /* start the spinner */
           child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
@@ -2079,24 +2123,26 @@ thunar_shortcuts_view_unmount (ThunarShortcutsView *view)
     {
       /* determine the device/mount for the shortcut at the given tree iterator */
       gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_DEVICE, &device, -1);
-      _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
 
-      /* prepare a mount operation */
-      mount_operation = thunar_gtk_mount_operation_new (GTK_WIDGET (view));
+      if (G_LIKELY (THUNAR_IS_DEVICE (device)))
+        {
+          /* prepare a mount operation */
+          mount_operation = thunar_gtk_mount_operation_new (GTK_WIDGET (view));
 
-      /* start the spinner */
-      child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
-      thunar_shortcuts_model_set_busy (THUNAR_SHORTCUTS_MODEL (child_model), device, TRUE);
+          /* start the spinner */
+          child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
+          thunar_shortcuts_model_set_busy (THUNAR_SHORTCUTS_MODEL (child_model), device, TRUE);
 
-      /* try to unmount */
-      thunar_device_unmount (device,
-                             mount_operation,
-                             NULL,
-                             thunar_shortcuts_view_unmount_finish,
-                             g_object_ref (view));
+          /* try to unmount */
+          thunar_device_unmount (device,
+                                 mount_operation,
+                                 NULL,
+                                 thunar_shortcuts_view_unmount_finish,
+                                 g_object_ref (view));
 
-      g_object_unref (G_OBJECT (device));
-      g_object_unref (G_OBJECT (mount_operation));
+          g_object_unref (G_OBJECT (device));
+          g_object_unref (G_OBJECT (mount_operation));
+        }
     }
 }
 
@@ -2165,3 +2211,18 @@ thunar_shortcuts_view_select_by_file (ThunarShortcutsView *view,
   else
      gtk_tree_selection_unselect_all (selection);
 }
+
+
+
+void
+thunar_shortcuts_view_toggle_padding (ThunarShortcutsView *view,
+                                      gboolean             enable)
+{
+  gtk_tree_view_column_set_attributes (view->column, view->padding_renderer,
+                                       "visible", enable ?
+                                          THUNAR_SHORTCUTS_MODEL_COLUMN_CAN_EJECT :
+                                          THUNAR_SHORTCUTS_MODEL_COLUMN_HIDDEN,
+                                       NULL);
+
+  view->padding_enabled = enable;
+}
diff --git a/thunar/thunar-shortcuts-view.h b/thunar/thunar-shortcuts-view.h
index 5f81f0b2..3a0a3087 100644
--- a/thunar/thunar-shortcuts-view.h
+++ b/thunar/thunar-shortcuts-view.h
@@ -41,6 +41,9 @@ GtkWidget *thunar_shortcuts_view_new             (void) G_GNUC_MALLOC;
 void       thunar_shortcuts_view_select_by_file  (ThunarShortcutsView *view,
                                                   ThunarFile           *file);
 
+void       thunar_shortcuts_view_toggle_padding  (ThunarShortcutsView *view,
+                                                  gboolean             enable);
+
 G_END_DECLS;
 
 #endif /* !__THUNAR_SHORTCUTS_VIEW_H__ */
diff --git a/thunar/thunar-side-pane.c b/thunar/thunar-side-pane.c
index 6084738a..e17c6305 100644
--- a/thunar/thunar-side-pane.c
+++ b/thunar/thunar-side-pane.c
@@ -41,7 +41,7 @@ thunar_side_pane_get_type (void)
       type = g_type_register_static_simple (G_TYPE_INTERFACE,
                                             I_("ThunarSidePane"),
                                             sizeof (ThunarSidePaneIface),
-                                            (GClassInitFunc) thunar_side_pane_class_init,
+                                            (GClassInitFunc) (void (*)(void)) thunar_side_pane_class_init,
                                             0,
                                             NULL,
                                             0);
diff --git a/thunar/thunar-standard-view-ui.xml b/thunar/thunar-standard-view-ui.xml
index 2a1c609d..6972427f 100644
--- a/thunar/thunar-standard-view-ui.xml
+++ b/thunar/thunar-standard-view-ui.xml
@@ -9,6 +9,7 @@
   -->
 
   <accelerator action="zoom-in-alt"/>
+  <accelerator action="open-location-alt"/>
 
   <menubar name="main-menu">
     <menu action="file-menu">
diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c
index f2ce4e4e..3115eec0 100644
--- a/thunar/thunar-standard-view.c
+++ b/thunar/thunar-standard-view.c
@@ -44,6 +44,7 @@
 #include <thunar/thunar-icon-renderer.h>
 #include <thunar/thunar-marshal.h>
 #include <thunar/thunar-menu-util.h>
+#include <thunar/thunar-pango-extensions.h>
 #include <thunar/thunar-private.h>
 #include <thunar/thunar-properties-dialog.h>
 #include <thunar/thunar-renamer-dialog.h>
@@ -60,10 +61,6 @@
 
 
 
-#define THUNAR_STANDARD_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNAR_TYPE_STANDARD_VIEW, ThunarStandardViewPrivate))
-
-
-
 /* Property identifiers */
 enum
 {
@@ -161,8 +158,7 @@ static ThunarFile          *thunar_standard_view_get_drop_file              (Thu
                                                                              gint                      x,
                                                                              gint                      y,
                                                                              GtkTreePath             **path_return);
-static void                 thunar_standard_view_merge_custom_actions       (ThunarStandardView       *standard_view,
-                                                                             GList                    *selected_items);
+static void                 thunar_standard_view_merge_custom_actions       (ThunarStandardView       *standard_view);
 static void                 thunar_standard_view_update_statusbar_text      (ThunarStandardView       *standard_view);
 static void                 thunar_standard_view_current_directory_destroy  (ThunarFile               *current_directory,
                                                                              ThunarStandardView       *standard_view);
@@ -349,6 +345,7 @@ struct _ThunarStandardViewPrivate
   GList                  *drag_g_file_list;
   guint                   drag_scroll_timer_id;
   guint                   drag_timer_id;
+  GdkEvent               *drag_timer_event;
   gint                    drag_x;
   gint                    drag_y;
 
@@ -443,7 +440,8 @@ static GParamSpec *standard_view_props[N_PROPERTIES] = { NULL, };
 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (ThunarStandardView, thunar_standard_view, GTK_TYPE_SCROLLED_WINDOW,
     G_IMPLEMENT_INTERFACE (THUNAR_TYPE_NAVIGATOR, thunar_standard_view_navigator_init)
     G_IMPLEMENT_INTERFACE (THUNAR_TYPE_COMPONENT, thunar_standard_view_component_init)
-    G_IMPLEMENT_INTERFACE (THUNAR_TYPE_VIEW, thunar_standard_view_view_init))
+    G_IMPLEMENT_INTERFACE (THUNAR_TYPE_VIEW, thunar_standard_view_view_init)
+    G_ADD_PRIVATE (ThunarStandardView))
 
 
 
@@ -455,8 +453,6 @@ thunar_standard_view_class_init (ThunarStandardViewClass *klass)
   GObjectClass   *gobject_class;
   gpointer        g_iface;
 
-  g_type_class_add_private (klass, sizeof (ThunarStandardViewPrivate));
-
   gobject_class = G_OBJECT_CLASS (klass);
   gobject_class->constructor = thunar_standard_view_constructor;
   gobject_class->dispose = thunar_standard_view_dispose;
@@ -635,7 +631,7 @@ thunar_standard_view_view_init (ThunarViewIface *iface)
 static void
 thunar_standard_view_init (ThunarStandardView *standard_view)
 {
-  standard_view->priv = THUNAR_STANDARD_VIEW_GET_PRIVATE (standard_view);
+  standard_view->priv = thunar_standard_view_get_instance_private (standard_view);
 
   /* allocate the scroll_to_files mapping (directory GFile -> first visible child GFile) */
   standard_view->priv->scroll_to_files = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, g_object_unref, g_object_unref);
@@ -718,9 +714,12 @@ G_GNUC_END_IGNORE_DEPRECATIONS
 
   /* setup the name renderer */
   standard_view->name_renderer = g_object_new (GTK_TYPE_CELL_RENDERER_TEXT,
+#if PANGO_VERSION_CHECK (1, 44, 0)
+                                               "attributes", thunar_pango_attr_disable_hyphens (),
+#endif
                                                "alignment", PANGO_ALIGN_CENTER,
                                                "xalign", 0.5,
-                                               FALSE);
+                                               NULL);
   g_object_ref_sink (G_OBJECT (standard_view->name_renderer));
 
   /* TODO: prelit underline
@@ -849,6 +848,13 @@ thunar_standard_view_dispose (GObject *object)
   if (G_UNLIKELY (standard_view->priv->drag_timer_id != 0))
     g_source_remove (standard_view->priv->drag_timer_id);
 
+  /* be sure to free any pending drag timer event */
+  if (G_UNLIKELY (standard_view->priv->drag_timer_event != NULL))
+    {
+      gdk_event_free (standard_view->priv->drag_timer_event);
+      standard_view->priv->drag_timer_event = NULL;
+    }
+
   /* reset the UI manager property */
   thunar_component_set_ui_manager (THUNAR_COMPONENT (standard_view), NULL);
 
@@ -1742,11 +1748,19 @@ thunar_standard_view_reload (ThunarView *view,
 {
   ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view);
   ThunarFolder       *folder;
+  ThunarFile         *file;
 
   /* determine the folder for the view model */
   folder = thunar_list_model_get_folder (standard_view->model);
   if (G_LIKELY (folder != NULL))
-    thunar_folder_reload (folder, reload_info);
+    {
+      file = thunar_folder_get_corresponding_file (folder);
+
+      if (thunar_file_exists (file))
+          thunar_folder_reload (folder, reload_info);
+      else
+          thunar_standard_view_current_directory_destroy (file, standard_view);
+    }
 
   /* schedule thumbnail reload update */
   if (!standard_view->priv->thumbnailing_scheduled)
@@ -2015,8 +2029,7 @@ thunar_standard_view_get_drop_file (ThunarStandardView *standard_view,
 
 
 static void
-thunar_standard_view_merge_custom_actions (ThunarStandardView *standard_view,
-                                           GList              *selected_items)
+thunar_standard_view_merge_custom_actions (ThunarStandardView *standard_view)
 {
   GtkTreeIter      iter;
   ThunarFile      *file = NULL;
@@ -2026,6 +2039,7 @@ thunar_standard_view_merge_custom_actions (ThunarStandardView *standard_view,
   GList           *files = NULL;
   GList           *tmp;
   GList           *lp;
+  GList           *selected_items;
   gchar           *path;
 
   /* we cannot add anything if we aren't connected to any UI manager */
@@ -2035,6 +2049,9 @@ thunar_standard_view_merge_custom_actions (ThunarStandardView *standard_view,
   /* determine the toplevel window we belong to */
   window = gtk_widget_get_toplevel (GTK_WIDGET (standard_view));
 
+  /* get the selected items */
+  selected_items = (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_selected_items) (standard_view);
+
   /* load the menu providers from the provider factory */
   providers = thunarx_provider_factory_list_providers (standard_view->priv->provider_factory, THUNARX_TYPE_MENU_PROVIDER);
   if (G_LIKELY (providers != NULL))
@@ -3073,6 +3090,8 @@ thunar_standard_view_motion_notify_event (GtkWidget          *view,
                                           GdkEventMotion     *event,
                                           ThunarStandardView *standard_view)
 {
+  GtkTargetList  *target_list;
+
   _thunar_return_val_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view), FALSE);
   _thunar_return_val_if_fail (standard_view->priv->drag_timer_id != 0, FALSE);
 
@@ -3081,11 +3100,19 @@ thunar_standard_view_motion_notify_event (GtkWidget          *view,
     {
       /* cancel the drag timer, as we won't popup the menu anymore */
       g_source_remove (standard_view->priv->drag_timer_id);
+      gdk_event_free (standard_view->priv->drag_timer_event);
+      standard_view->priv->drag_timer_event = NULL;
+
+      /* allocate the drag context */
+      target_list = gtk_target_list_new (drag_targets, G_N_ELEMENTS (drag_targets));
+      gtk_drag_begin_with_coordinates (view, target_list,
+                                       GDK_ACTION_COPY |
+                                       GDK_ACTION_MOVE |
+                                       GDK_ACTION_LINK |
+                                       GDK_ACTION_ASK,
+                                       3, (GdkEvent *) event, -1, -1);
+      gtk_target_list_unref (target_list);
 
-      /* FIXME
-       * - according to doc, the GdkWindow associated to the widget needs to enable the GDK_POINTER_MOTION_MASK mask to use this event.
-       * We dont do that. So possibly this is dead code, which can be removed ?
-      */
       return TRUE;
     }
 
@@ -3099,12 +3126,29 @@ thunar_standard_view_scroll_event (GtkWidget          *view,
                                    GdkEventScroll     *event,
                                    ThunarStandardView *standard_view)
 {
-  GdkEventButton fake_event;
-  gboolean       misc_horizontal_wheel_navigates;
+  GdkEventButton     fake_event;
+  GdkScrollDirection scrolling_direction;
+  gboolean           misc_horizontal_wheel_navigates;
 
   _thunar_return_val_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view), FALSE);
 
-  if (G_UNLIKELY (event->direction == GDK_SCROLL_LEFT || event->direction == GDK_SCROLL_RIGHT))
+  if (event->direction != GDK_SCROLL_SMOOTH)
+    scrolling_direction = event->direction;
+  else if (event->delta_y < 0)
+    scrolling_direction = GDK_SCROLL_UP;
+  else if (event->delta_y > 0)
+    scrolling_direction = GDK_SCROLL_DOWN;
+  else if (event->delta_x < 0)
+    scrolling_direction = GDK_SCROLL_LEFT;
+  else if (event->delta_x > 0)
+    scrolling_direction = GDK_SCROLL_RIGHT;
+  else
+    {
+      g_debug ("GDK_SCROLL_SMOOTH scrolling event with no delta happened");
+      return TRUE;
+    }
+
+  if (G_UNLIKELY (scrolling_direction == GDK_SCROLL_LEFT || scrolling_direction == GDK_SCROLL_RIGHT))
     {
       /* check if we should use the horizontal mouse wheel for navigation */
       g_object_get (G_OBJECT (standard_view->preferences), "misc-horizontal-wheel-navigates", &misc_horizontal_wheel_navigates, NULL);
@@ -3112,7 +3156,7 @@ thunar_standard_view_scroll_event (GtkWidget          *view,
         {
           /* create a fake event (8 == back, 9 forward) */
           fake_event.type = GDK_BUTTON_PRESS;
-          fake_event.button = event->direction == GDK_SCROLL_LEFT ? 8 : 9;
+          fake_event.button = scrolling_direction == GDK_SCROLL_LEFT ? 8 : 9;
 
           /* trigger a fake button press event */
           return thunar_standard_view_button_press_event (view, &fake_event, standard_view);
@@ -3120,10 +3164,10 @@ thunar_standard_view_scroll_event (GtkWidget          *view,
     }
 
   /* zoom-in/zoom-out on control+mouse wheel */
-  if ((event->state & GDK_CONTROL_MASK) != 0 && (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_DOWN))
+  if ((event->state & GDK_CONTROL_MASK) != 0 && (scrolling_direction == GDK_SCROLL_UP || scrolling_direction == GDK_SCROLL_DOWN))
     {
       thunar_view_set_zoom_level (THUNAR_VIEW (standard_view),
-          (event->direction == GDK_SCROLL_UP)
+          (scrolling_direction == GDK_SCROLL_UP)
           ? MIN (standard_view->priv->zoom_level + 1, THUNAR_ZOOM_N_LEVELS - 1)
           : MAX (standard_view->priv->zoom_level, 1) - 1);
       return TRUE;
@@ -4323,18 +4367,23 @@ thunar_standard_view_context_menu (ThunarStandardView *standard_view)
 
   _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view));
 
-  /* merge the custom menu actions for the selected items */
-  selected_items = (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_selected_items) (standard_view);
-  thunar_standard_view_merge_custom_actions (standard_view, selected_items);
-
   /* grab an additional reference on the view */
   g_object_ref (G_OBJECT (standard_view));
 
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   /* run the menu (figuring out whether to use the file or the folder context menu) */
+  selected_items = (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_selected_items) (standard_view);
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   menu = gtk_ui_manager_get_widget (standard_view->ui_manager, (selected_items != NULL) ? "/file-context-menu" : "/folder-context-menu");
 G_GNUC_END_IGNORE_DEPRECATIONS
-  thunar_gtk_menu_run (GTK_MENU (menu));
+  /* if there is a drag_timer_event (long press), we use it */
+  if (standard_view->priv->drag_timer_event != NULL)
+    {
+      thunar_gtk_menu_run_at_event (GTK_MENU (menu), standard_view->priv->drag_timer_event);
+      gdk_event_free (standard_view->priv->drag_timer_event);
+      standard_view->priv->drag_timer_event = NULL;
+    }
+  else
+    thunar_gtk_menu_run (GTK_MENU (menu));
 
   g_list_free_full (selected_items, (GDestroyNotify) gtk_tree_path_free);
 
@@ -4389,6 +4438,8 @@ thunar_standard_view_queue_popup (ThunarStandardView *standard_view,
       /* schedule the timer */
       standard_view->priv->drag_timer_id = g_timeout_add_full (G_PRIORITY_LOW, MAX (225, delay), thunar_standard_view_drag_timer,
                                                                standard_view, thunar_standard_view_drag_timer_destroy);
+      /* store current event data */
+      standard_view->priv->drag_timer_event = gtk_get_current_event ();
 
       /* 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);
@@ -4415,9 +4466,11 @@ thunar_standard_view_selection_changed (ThunarStandardView *standard_view)
   ThunarFile *current_directory;
   gboolean    can_paste_into_folder;
   gboolean    restorable;
+  gboolean    trashable;
   gboolean    pastable;
   gboolean    writable;
   gboolean    trashed;
+  gboolean    hide_trash_action;
   gboolean    show_delete_action;
   GList      *lp, *selected_files;
   gint        n_selected_files = 0;
@@ -4438,6 +4491,7 @@ thunar_standard_view_selection_changed (ThunarStandardView *standard_view)
   /* determine the new list of selected files (replacing GtkTreePath's with ThunarFile's) */
   selected_files = (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_selected_items) (standard_view);
   restorable = (selected_files != NULL);
+  trashable = (selected_files != NULL);
   for (lp = selected_files; lp != NULL; lp = lp->next, ++n_selected_files)
     {
       /* determine the iterator for the path */
@@ -4452,6 +4506,10 @@ thunar_standard_view_selection_changed (ThunarStandardView *standard_view)
       /* enable "Restore" if we have only trashed files (atleast one file) */
       if (!thunar_file_is_trashed (lp->data))
         restorable = FALSE;
+
+      /* enable "Move to Trash" if files can be trashed */
+      if (!thunar_file_can_be_trashed (lp->data))
+        trashable = FALSE;
     }
 
   /* and setup the new selected files list */
@@ -4462,6 +4520,10 @@ thunar_standard_view_selection_changed (ThunarStandardView *standard_view)
   writable = (current_directory != NULL && thunar_file_is_writable (current_directory));
   trashed = (current_directory != NULL && thunar_file_is_trashed (current_directory));
 
+  /* if moving to trash is not applicable, replace it with the delete action
+   * but only if the directory is writable -- keep "move to trash" otherwise */
+  hide_trash_action = writable && (trashed || !trashable || !thunar_g_vfs_is_uri_scheme_supported ("trash"));
+
   g_object_get (G_OBJECT (standard_view->preferences), "misc-show-delete-action", &show_delete_action, NULL);
 
   /* check whether the clipboard contains data that can be pasted here */
@@ -4507,7 +4569,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
   /* update the "Move to Trash" action */
   g_object_set (G_OBJECT (standard_view->priv->action_move_to_trash),
                 "sensitive", (n_selected_files > 0) && writable,
-                "visible", !trashed && thunar_g_vfs_is_uri_scheme_supported ("trash"),
+                "visible", !hide_trash_action,
                 "tooltip", ngettext ("Move the selected file to the Trash",
                                      "Move the selected files to the Trash",
                                      n_selected_files),
@@ -4516,7 +4578,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
   /* update the "Delete" action */
   g_object_set (G_OBJECT (standard_view->priv->action_delete),
                 "sensitive", (n_selected_files > 0) && writable,
-                "visible", trashed || !thunar_g_vfs_is_uri_scheme_supported ("trash") || show_delete_action,
+                "visible", hide_trash_action || show_delete_action,
                 "tooltip", ngettext ("Permanently delete the selected file",
                                      "Permanently delete the selected files",
                                      n_selected_files),
@@ -4564,6 +4626,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
   /* update the statusbar text */
   thunar_standard_view_update_statusbar_text (standard_view);
 
+  /* merge the custom actions */
+  thunar_standard_view_merge_custom_actions (standard_view);
+
   /* emit notification for "selected-files" */
   g_object_notify_by_pspec (G_OBJECT (standard_view), standard_view_props[PROP_SELECTED_FILES]);
 }
diff --git a/thunar/thunar-templates-action.c b/thunar/thunar-templates-action.c
index 33a263d8..c60956c8 100644
--- a/thunar/thunar-templates-action.c
+++ b/thunar/thunar-templates-action.c
@@ -25,8 +25,7 @@
 #include <gio/gio.h>
 
 #include <thunar/thunar-icon-factory.h>
-#include <thunar/thunar-job.h>
-#include <thunar/thunar-misc-jobs.h>
+#include <thunar/thunar-io-scan-directory.h>
 #include <thunar/thunar-private.h>
 #include <thunar/thunar-templates-action.h>
 #include <thunar/thunar-util.h>
@@ -44,7 +43,7 @@ enum
 
 static void       thunar_templates_action_finalize          (GObject                    *object);
 static GtkWidget *thunar_templates_action_create_menu_item  (GtkAction                  *action);
-static void       thunar_templates_action_menu_shown        (GtkWidget                  *menu,
+static void       thunar_templates_action_load              (GtkWidget                  *menu,
                                                              ThunarTemplatesAction      *templates_action);
 
 
@@ -167,9 +166,10 @@ G_GNUC_END_IGNORE_DEPRECATIONS
 
   /* associate an empty submenu with the item (will be filled when shown) */
   menu = gtk_menu_new ();
-  g_signal_connect (G_OBJECT (menu), "show", G_CALLBACK (thunar_templates_action_menu_shown), action);
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
 
+  thunar_templates_action_load (menu, THUNAR_TEMPLATES_ACTION (action));
+
   return item;
 }
 
@@ -310,14 +310,13 @@ compare_files (ThunarFile *a,
 
 
 static gboolean
-thunar_templates_action_files_ready (ThunarJob             *job,
-                                     GList                 *files,
-                                     ThunarTemplatesAction *templates_action)
+thunar_templates_action_set_files (GtkWidget             *menu,
+                                   GList                 *files,
+                                   ThunarTemplatesAction *templates_action)
 {
   ThunarIconFactory *icon_factory;
   ThunarFile        *file;
   GdkPixbuf         *icon;
-  GtkWidget         *menu;
   GtkWidget         *parent_menu;
   GtkWidget         *submenu;
   GtkWidget         *image;
@@ -331,9 +330,6 @@ thunar_templates_action_files_ready (ThunarJob             *job,
   gchar             *label;
   gchar             *dot;
 
-  /* determine the menu to add the items and submenus to */
-  menu = g_object_get_data (G_OBJECT (job), "menu");
-
   /* do nothing if there is no menu */
   if (menu == NULL)
     return FALSE;
@@ -343,7 +339,7 @@ thunar_templates_action_files_ready (ThunarJob             *job,
 
   /* sort items so that directories come before files and ancestors come
    * before descendants */
-  files = g_list_sort (files, (GCompareFunc) compare_files);
+  files = g_list_sort (files, (GCompareFunc) (void (*)(void)) compare_files);
 
   for (lp = g_list_first (files); lp != NULL; lp = lp->next)
     {
@@ -447,26 +443,21 @@ G_GNUC_END_IGNORE_DEPRECATIONS
 
 
 static void
-thunar_templates_action_load_error (ThunarJob             *job,
-                                    GError                *error,
-                                    ThunarTemplatesAction *templates_action)
+thunar_templates_action_set_error (GtkWidget             *menu,
+                                   const gchar           *error_message,
+                                   ThunarTemplatesAction *templates_action)
 {
   GtkWidget *item;
-  GtkWidget *menu;
   GList     *menu_children = NULL;
 
-  _thunar_return_if_fail (THUNAR_IS_JOB (job));
-  _thunar_return_if_fail (error != NULL);
+  _thunar_return_if_fail (error_message != NULL);
   _thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action));
-  _thunar_return_if_fail (templates_action->job == job);
-
-  menu = g_object_get_data (G_OBJECT (job), "menu");
 
   /* check if any items were added to the menu */
   if (G_LIKELY (menu != NULL && (menu_children = gtk_container_get_children( GTK_CONTAINER (menu))) == NULL))
     {
       /* tell the user that no templates were found */
-      item = gtk_menu_item_new_with_label (error->message);
+      item = gtk_menu_item_new_with_label (error_message);
       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
       gtk_widget_set_sensitive (item, FALSE);
       gtk_widget_show (item);
@@ -478,17 +469,14 @@ thunar_templates_action_load_error (ThunarJob             *job,
 
 
 static void
-thunar_templates_action_load_finished (ThunarJob             *job,
+thunar_templates_action_load_finished (GtkWidget             *menu,
                                        ThunarTemplatesAction *templates_action)
 {
+  GtkWidget *image;
   GtkWidget *item;
-  GtkWidget *menu;
 
-  _thunar_return_if_fail (THUNAR_IS_JOB (job));
   _thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action));
-  _thunar_return_if_fail (templates_action->job == job);
 
-  menu = g_object_get_data (G_OBJECT (job), "menu");
   if (G_LIKELY (menu != NULL))
     {
       /* append a menu separator */
@@ -497,49 +485,67 @@ thunar_templates_action_load_finished (ThunarJob             *job,
       gtk_widget_show (item);
 
       /* add the "Empty File" item */
-      item = gtk_menu_item_new_with_mnemonic (_("_Empty File"));
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+      item = gtk_image_menu_item_new_with_mnemonic (_("_Empty File"));
+G_GNUC_END_IGNORE_DEPRECATIONS
       g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (item_activated),
                         templates_action);
       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
       gtk_widget_show (item);
-    }
 
-  g_signal_handlers_disconnect_matched (job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL,
-                                        templates_action);
-  g_object_unref (job);
+      /* add the icon for the emtpy file item */
+      image = gtk_image_new_from_icon_name ("text-x-generic", GTK_ICON_SIZE_MENU);
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+      gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+G_GNUC_END_IGNORE_DEPRECATIONS
+    }
 }
 
 
 
 static void
-thunar_templates_action_menu_shown (GtkWidget             *menu,
-                                    ThunarTemplatesAction *templates_action)
+thunar_templates_action_load (GtkWidget             *menu,
+                              ThunarTemplatesAction *templates_action)
 {
-  GList *children;
+  GList           *files = NULL;
+  GFile           *home_dir;
+  GFile           *templates_dir;
+  const gchar     *path;
 
   _thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action));
   _thunar_return_if_fail (GTK_IS_MENU_SHELL (menu));
 
-  /* drop all existing children of the menu first */
-  children = gtk_container_get_children (GTK_CONTAINER (menu));
-  g_list_free_full (children, (GDestroyNotify) gtk_widget_destroy);
+  home_dir = thunar_g_file_new_for_home ();
+  path = g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES);
 
-  if (G_LIKELY (templates_action->job == NULL))
+  if (G_LIKELY (path != NULL))
+    templates_dir = g_file_new_for_path (path);
+  else
+    templates_dir = g_file_resolve_relative_path (home_dir, "Templates");
+
+  if (G_LIKELY (!g_file_equal (templates_dir, home_dir)))
     {
-      templates_action->job = thunar_misc_jobs_load_template_files (menu);
-      g_object_add_weak_pointer (G_OBJECT (templates_action->job),
-                                 (gpointer) &templates_action->job);
+      /* load the ThunarFiles */
+      files = thunar_io_scan_directory (NULL, templates_dir,
+                                        G_FILE_QUERY_INFO_NONE,
+                                        TRUE, FALSE, TRUE, NULL);
+    }
 
-      g_signal_connect (templates_action->job, "files-ready",
-                        G_CALLBACK (thunar_templates_action_files_ready),
-                        templates_action);
-      g_signal_connect (templates_action->job, "error",
-                        G_CALLBACK (thunar_templates_action_load_error),
-                        templates_action);
-      g_signal_connect (templates_action->job, "finished",
-                        G_CALLBACK (thunar_templates_action_load_finished),
-                        templates_action);
+  g_object_unref (templates_dir);
+  g_object_unref (home_dir);
+
+  if (files == NULL)
+    {
+      thunar_templates_action_set_error (menu, _("No templates installed"),
+                                         templates_action);
+    }
+  else
+    {
+      thunar_templates_action_set_files (menu, files, templates_action);
+      thunar_g_file_list_free (files);
     }
+
+  thunar_templates_action_load_finished (menu, templates_action);
 }
 
 
diff --git a/thunar/thunar-thumbnailer.c b/thunar/thunar-thumbnailer.c
index 0c45fd0b..4be88b4c 100644
--- a/thunar/thunar-thumbnailer.c
+++ b/thunar/thunar-thumbnailer.c
@@ -356,8 +356,15 @@ thunar_thumbnailer_queue_async_reply (GObject      *proxy,
     }
   else if (error == NULL)
     {
-      /* store the handle returned by tumbler */
-      job->handle = handle;
+      if (handle == 0)
+        {
+          g_printerr ("ThunarThumbnailer: got 0 handle (Queue)\n");
+        }
+      else
+        {
+          /* store the handle returned by tumbler */
+          job->handle = handle;
+        }
     }
   else
     {
@@ -871,6 +878,12 @@ thunar_thumbnailer_thumbnailer_finished (GDBusProxy        *proxy,
   _thunar_return_if_fail (G_IS_DBUS_PROXY (proxy));
   _thunar_return_if_fail (THUNAR_IS_THUMBNAILER (thumbnailer));
 
+  if (handle == 0)
+    {
+      g_printerr ("ThunarThumbnailer: got 0 handle (Finished)\n");
+      return;
+    }
+
   _thumbnailer_lock (thumbnailer);
 
   for (lp = thumbnailer->jobs; lp != NULL; lp = lp->next)
@@ -912,6 +925,12 @@ thunar_thumbnailer_idle (ThunarThumbnailer          *thumbnailer,
   if (G_UNLIKELY (uris == NULL))
     return;
 
+  if (handle == 0)
+    {
+      g_printerr ("ThunarThumbnailer: got 0 handle (Error or Ready)\n");
+      return;
+    }
+
   _thumbnailer_lock (thumbnailer);
 
   /* look for the job so we don't emit unknown handles, the reason
@@ -1089,7 +1108,7 @@ thunar_thumbnailer_queue_files (ThunarThumbnailer *thumbnailer,
   /* allocate a job */
   job = g_slice_new0 (ThunarThumbnailerJob);
   job->thumbnailer = thumbnailer;
-  job->files = g_list_copy_deep (files, (GCopyFunc)g_object_ref, NULL);
+  job->files = g_list_copy_deep (files, (GCopyFunc) (void (*)(void)) g_object_ref, NULL);
   job->lazy_checks = lazy_checks ? 1 : 0;
 
   success = thunar_thumbnailer_begin_job (thumbnailer, job);
diff --git a/thunar/thunar-transfer-job.c b/thunar/thunar-transfer-job.c
index 570f28a2..f7d75598 100644
--- a/thunar/thunar-transfer-job.c
+++ b/thunar/thunar-transfer-job.c
@@ -103,6 +103,7 @@ struct _ThunarTransferNode
   ThunarTransferNode *next;
   ThunarTransferNode *children;
   GFile              *source_file;
+  gboolean            replace_confirmed;
 };
 
 
@@ -318,6 +319,7 @@ thunar_transfer_job_collect_node (ThunarTransferJob  *job,
           /* allocate a new transfer node for the child */
           child_node = g_slice_new0 (ThunarTransferNode);
           child_node->source_file = g_object_ref (lp->data);
+          child_node->replace_confirmed = node->replace_confirmed;
 
           /* hook the child node into the child list */
           child_node->next = node->children;
@@ -471,12 +473,15 @@ ttj_copy_file (ThunarTransferJob *job,
  * @job                : a #ThunarTransferJob.
  * @source_file        : the source #GFile to copy.
  * @target_file        : the destination #GFile to copy to.
+ * @replace_confirmed  : whether the user has already confirmed that this file should replace an existing one
  * @error              : return location for errors or %NULL.
  *
  * Tries to copy @source_file to @target_file. The real destination is the
  * return value and may differ from @target_file (e.g. if you try to copy
  * the file "/foo/bar" into the same directory you'll end up with something
- * like "/foo/copy of bar" instead of "/foo/bar".
+ * like "/foo/copy of bar" instead of "/foo/bar"). If an existing file would
+ * be replaced, the user is asked to confirm this unless @replace_confirmed
+ * is TRUE.
  *
  * The return value is guaranteed to be %NULL on errors and @error will
  * always be set in those cases. If the file is skipped, the return value
@@ -492,6 +497,7 @@ static GFile *
 thunar_transfer_job_copy_file (ThunarTransferJob *job,
                                GFile             *source_file,
                                GFile             *target_file,
+                               gboolean           replace_confirmed,
                                GError           **error)
 {
   ThunarJobResponse response;
@@ -555,17 +561,16 @@ thunar_transfer_job_copy_file (ThunarTransferJob *job,
           /* reset the error */
           g_clear_error (&err);
 
-          /* ask the user whether to replace the target file */
-          response = thunar_job_ask_replace (THUNAR_JOB (job), source_file,
-                                             target_file, &err);
+          /* if necessary, ask the user whether to replace the target file */
+          if(replace_confirmed)
+            response = THUNAR_JOB_RESPONSE_YES;
+          else
+            response = thunar_job_ask_replace (THUNAR_JOB (job), source_file,
+                                               target_file, &err);
 
           if (err != NULL)
             break;
 
-          /* check if we should retry */
-          if (response == THUNAR_JOB_RESPONSE_RETRY)
-            continue;
-
           /* add overwrite flag and retry if we should overwrite */
           if (response == THUNAR_JOB_RESPONSE_YES)
             {
@@ -652,7 +657,7 @@ thunar_transfer_job_copy_node (ThunarTransferJob  *job,
 retry_copy:
       /* copy the item specified by this node (not recursively) */
       real_target_file = thunar_transfer_job_copy_file (job, node->source_file,
-                                                        target_file, &err);
+                                                        target_file, node->replace_confirmed, &err);
       if (G_LIKELY (real_target_file != NULL))
         {
           /* node->source_file == real_target_file means to skip the file */
@@ -827,15 +832,11 @@ thunar_transfer_job_verify_destination (ThunarTransferJob  *transfer_job,
         }
     }
 
-  if (succeed && g_file_info_get_attribute_boolean (filesystem_info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY))
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_READ_ONLY,
-                   _("Error while copying to \"%s\": The destination is read-only"),
-                   dest_name);
-
-      /* meh */
-      succeed = FALSE;
-    }
+  /* We used to check G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE here,
+   * but it's not completely reliable, especially on remote file systems.
+   * The downside is that operations on read-only files fail with a generic
+   * error message.
+   * More details: https://bugzilla.xfce.org/show_bug.cgi?id=15367#c16 */
 
   g_object_unref (filesystem_info);
   g_object_unref (G_OBJECT (dest));
@@ -858,6 +859,7 @@ thunar_transfer_job_execute (ExoJob  *job,
   GFileInfo            *info;
   GFileCopyFlags        flags;
   gboolean              parent_exists;
+  gboolean              move_successful;
   GError               *err = NULL;
   GList                *new_files_list = NULL;
   GList                *snext;
@@ -927,6 +929,7 @@ thunar_transfer_job_execute (ExoJob  *job,
           if (exo_job_set_error_if_cancelled (job, &err))
             {
               g_object_unref (target_parent);
+              g_object_unref (info);
               break;
             }
 
@@ -950,6 +953,7 @@ thunar_transfer_job_execute (ExoJob  *job,
                 {
                   g_object_unref (target_parent);
                   g_free (parent_display_name);
+                  g_object_unref (info);
                   break;
                 }
 
@@ -970,6 +974,7 @@ thunar_transfer_job_execute (ExoJob  *job,
 
                   g_object_unref (target_parent);
                   g_free (parent_display_name);
+                  g_object_unref (info);
                   break;
                 }
 
@@ -987,18 +992,58 @@ thunar_transfer_job_execute (ExoJob  *job,
           exo_job_info_message (job, _("Trying to move \"%s\""),
                                 g_file_info_get_display_name (info));
 
-          if (g_file_move (node->source_file, tp->data,
-                           flags,
-                           exo_job_get_cancellable (job),
-                           NULL, NULL, &err))
+          /* try moving without overwriting */
+          move_successful = g_file_move (node->source_file, tp->data,
+                                         flags,
+                                         exo_job_get_cancellable (job),
+                                         NULL, NULL, &err);
+
+          /* if the file already exists, ask the user if they want to overwrite it */
+          if (!move_successful && err->code == G_IO_ERROR_EXISTS)
             {
-              /* notify the thumbnail cache of the move operation */
-              thunar_thumbnail_cache_move_file (thumbnail_cache,
-                                                node->source_file,
-                                                tp->data);
+              g_clear_error (&err);
+              response = thunar_job_ask_replace (THUNAR_JOB (job), node->source_file, tp->data, NULL);
 
-              /* add the target file to the new files list */
-              new_files_list = thunar_g_file_list_prepend (new_files_list, tp->data);
+              /* if the user chose to overwrite then try to do so */
+              if (response == THUNAR_JOB_RESPONSE_YES)
+                {
+                  node->replace_confirmed = TRUE;
+                  move_successful = g_file_move (node->source_file, tp->data,
+                                                 flags | G_FILE_COPY_OVERWRITE,
+                                                 exo_job_get_cancellable (job),
+                                                 NULL, NULL, &err);
+                }
+
+              /* if the user chose to cancel then abort all remaining file moves */
+              if (response == THUNAR_JOB_RESPONSE_CANCEL)
+                {
+                  /* release all the remaining source and target files, and free the lists */
+                  g_list_free_full (transfer_job->source_node_list, thunar_transfer_node_free);
+                  transfer_job->source_node_list = NULL;
+                  g_list_free_full (transfer_job->target_file_list, g_object_unref);
+                  transfer_job->target_file_list= NULL;
+                  g_object_unref (info);
+                  break;
+                }
+
+              /* if the user chose not to replace the file, so that response == THUNAR_JOB_RESPONSE_NO,
+               * then err will be NULL but move_successfull will be FALSE, so that the source and target
+               * files will be released and the matching list items will be dropped below
+               */
+            }
+
+          if (err == NULL)
+            {
+              if (move_successful)
+                {
+                  /* notify the thumbnail cache of the move operation */
+                  thunar_thumbnail_cache_move_file (thumbnail_cache,
+                                                    node->source_file,
+                                                    tp->data);
+
+                  /* add the target file to the new files list */
+                  new_files_list = thunar_g_file_list_prepend (new_files_list, tp->data);
+                }
 
               /* release source and target files */
               thunar_transfer_node_free (node);
@@ -1008,7 +1053,10 @@ thunar_transfer_job_execute (ExoJob  *job,
               transfer_job->source_node_list = g_list_delete_link (transfer_job->source_node_list, sp);
               transfer_job->target_file_list = g_list_delete_link (transfer_job->target_file_list, tp);
             }
-          else if (!exo_job_is_cancelled (job))
+          /* prepare for the fallback copy and delete if appropriate */
+          else if (!exo_job_is_cancelled (job) &&
+                   ((err->code == G_IO_ERROR_NOT_SUPPORTED) ||
+                    (err->code == G_IO_ERROR_WOULD_MERGE) || (err->code == G_IO_ERROR_WOULD_RECURSE)) )
             {
               g_clear_error (&err);
 
@@ -1017,14 +1065,12 @@ thunar_transfer_job_execute (ExoJob  *job,
                                            "Collecting files for copying..."),
                                     g_file_info_get_display_name (info));
 
-              if (!thunar_transfer_job_collect_node (transfer_job, node, &err))
-                {
-                  /* failed to collect, cannot continue */
-                  g_object_unref (info);
-                  break;
-                }
+              /* if this call fails to collect the node, err will be non-NULL and the loop will exit */
+              thunar_transfer_job_collect_node (transfer_job, node, &err);
             }
+
         }
+
       else if (transfer_job->type == THUNAR_TRANSFER_JOB_COPY)
         {
           if (!thunar_transfer_job_collect_node (THUNAR_TRANSFER_JOB (job), node, &err))
@@ -1144,6 +1190,7 @@ thunar_transfer_job_new (GList                *source_node_list,
           /* append transfer node for this source file */
           node = g_slice_new0 (ThunarTransferNode);
           node->source_file = g_object_ref (sp->data);
+          node->replace_confirmed = FALSE;
           job->source_node_list = g_list_append (job->source_node_list, node);
 
           /* append target file */
@@ -1222,4 +1269,3 @@ thunar_transfer_job_get_status (ThunarTransferJob *job)
 
   return g_string_free (status, FALSE);
 }
-
diff --git a/thunar/thunar-tree-model.c b/thunar/thunar-tree-model.c
index 3424f480..774a5e3d 100644
--- a/thunar/thunar-tree-model.c
+++ b/thunar/thunar-tree-model.c
@@ -295,7 +295,7 @@ thunar_tree_model_init (ThunarTreeModel *model)
 
   /* initialize the model data */
   model->sort_case_sensitive = TRUE;
-  model->visible_func = (ThunarTreeModelVisibleFunc) exo_noop_true;
+  model->visible_func = (ThunarTreeModelVisibleFunc) (void (*)(void)) exo_noop_true;
   model->visible_data = NULL;
   model->cleanup_idle_id = 0;
 
@@ -1075,23 +1075,37 @@ thunar_tree_model_device_added (ThunarDeviceMonitor *device_monitor,
   _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
   _thunar_return_if_fail (THUNAR_IS_TREE_MODEL (model));
 
+  /* lookup the last child of the root (the "File System" node) */
+  node = g_node_last_child (model->root);
+
+  /* determine the position for the new node in the item list */
+  for (node = node->prev; node != NULL; node = node->prev)
+    {
+      item = THUNAR_TREE_MODEL_ITEM (node->data);
+      if (item->device == NULL)
+        break;
+
+      /* sort devices by timestamp */
+      if (thunar_device_sort (item->device, device) < 0)
+        break;
+    }
+
   /* allocate a new item for the volume */
   item = thunar_tree_model_item_new_with_device (model, device);
 
-  /* insert before the last child of the root (the "File System" node) */
-  node = g_node_last_child (model->root);
-  node = g_node_insert_data_before (model->root, node, item);
+  /* insert the new node */
+  node = g_node_insert_data_after (model->root, node, item);
 
   /* determine the iterator for the new node */
   GTK_TREE_ITER_INIT (iter, model->stamp, node);
 
-  /* add the dummy node */
-  thunar_tree_model_node_insert_dummy (node, model);
-
   /* tell the view about the new node */
   path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
   gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter);
   gtk_tree_path_free (path);
+
+  /* add the dummy node */
+  thunar_tree_model_node_insert_dummy (node, model);
 }
 
 
diff --git a/thunar/thunar-tree-view.c b/thunar/thunar-tree-view.c
index 3ac367e4..0db3b202 100644
--- a/thunar/thunar-tree-view.c
+++ b/thunar/thunar-tree-view.c
@@ -142,6 +142,8 @@ static GdkDragAction            thunar_tree_view_get_dest_actions             (T
                                                                                ThunarFile             **file_return);
 static ThunarFile              *thunar_tree_view_get_selected_file            (ThunarTreeView          *view);
 static ThunarDevice            *thunar_tree_view_get_selected_device          (ThunarTreeView          *view);
+static void                     thunar_tree_view_action_unlink_selected_folder(ThunarTreeView          *view,
+                                                                               gboolean                 permanently);
 static void                     thunar_tree_view_action_copy                  (ThunarTreeView          *view);
 static void                     thunar_tree_view_action_create_folder         (ThunarTreeView          *view);
 static void                     thunar_tree_view_action_cut                   (ThunarTreeView          *view);
@@ -1230,7 +1232,8 @@ thunar_tree_view_row_collapsed (GtkTreeView *tree_view,
 static gboolean
 thunar_tree_view_delete_selected_files (ThunarTreeView *view)
 {
-  GtkAccelKey key;
+  GtkAccelKey     key;
+  GdkModifierType state;
 
   _thunar_return_val_if_fail (THUNAR_IS_TREE_VIEW (view), FALSE);
 
@@ -1241,8 +1244,12 @@ thunar_tree_view_delete_selected_files (ThunarTreeView *view)
       && (key.accel_key != 0 || key.accel_mods != 0))
     return FALSE;
 
-  /* ask the user whether to delete the folder... */
-  thunar_tree_view_action_move_to_trash (view);
+  /* check if we should permanently delete the files (user holds shift or no gvfs available) */
+  if ((gtk_get_current_event_state (&state) && (state & GDK_SHIFT_MASK) != 0) ||
+      (gtk_get_current_event_state (&state) && !thunar_g_vfs_is_uri_scheme_supported ("trash")))
+    thunar_tree_view_action_delete (view);
+  else
+    thunar_tree_view_action_move_to_trash (view);
 
   /* ...and we're done */
   return TRUE;
@@ -1265,6 +1272,7 @@ thunar_tree_view_context_menu (ThunarTreeView *view,
   GIcon        *icon;
   GList        *providers, *lp;
   GList        *items = NULL, *tmp;
+  gboolean      show_delete_action;
 
   /* verify that we're connected to the clipboard manager */
   if (G_UNLIKELY (view->clipboard == NULL))
@@ -1351,7 +1359,12 @@ G_GNUC_END_IGNORE_DEPRECATIONS
       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
       gtk_widget_show (item);
     }
-  else if (G_UNLIKELY (file != NULL && thunar_file_is_trashed (file) && thunar_file_is_root (file)))
+
+  if (G_UNLIKELY (file == NULL))
+    {
+      /* do nothing */
+    }
+  else if (G_UNLIKELY (thunar_g_file_is_trash (thunar_file_get_file (file))))
     {
       /* append the "Empty Trash" menu action */
       item = gtk_menu_item_new_with_mnemonic (_("_Empty Trash"));
@@ -1365,35 +1378,34 @@ G_GNUC_END_IGNORE_DEPRECATIONS
       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
       gtk_widget_show (item);
     }
-
-  /* check if we have a non-trashed resource */
-  if (G_LIKELY (file != NULL && !thunar_file_is_trashed (file)))
+  else
     {
-      /* append the "Create Folder" menu action */
+      /* check if we have a non-trashed resource */
+      if (G_LIKELY (!thunar_file_is_trashed (file)))
+        {
+          /* append the "Create Folder" menu action */
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-      item = gtk_image_menu_item_new_with_mnemonic (_("Create _Folder..."));
+          item = gtk_image_menu_item_new_with_mnemonic (_("Create _Folder..."));
 G_GNUC_END_IGNORE_DEPRECATIONS
-      gtk_widget_set_sensitive (item, thunar_file_is_writable (file));
-      g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_tree_view_action_create_folder), view);
-      gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-      gtk_widget_show (item);
+          gtk_widget_set_sensitive (item, thunar_file_is_writable (file));
+          g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_tree_view_action_create_folder), view);
+          gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+          gtk_widget_show (item);
 
-      /* set the icon */
-      icon = g_themed_icon_new ("folder-new");
-      image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_MENU);
+          /* set the icon */
+          icon = g_themed_icon_new ("folder-new");
+          image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_MENU);
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-      gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+          gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
 G_GNUC_END_IGNORE_DEPRECATIONS
-      g_object_unref (icon);
+          g_object_unref (icon);
 
-      /* append a separator item */
-      item = gtk_separator_menu_item_new ();
-      gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-      gtk_widget_show (item);
-    }
+          /* append a separator item */
+          item = gtk_separator_menu_item_new ();
+          gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+          gtk_widget_show (item);
+        }
 
-  if (G_LIKELY (file != NULL))
-    {
       /* "Cut" and "Copy" don't make much sense for devices */
       if (G_LIKELY (device == NULL))
         {
@@ -1454,6 +1466,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS
       /* "Delete" and "Rename" don't make much sense for devices */
       if (G_LIKELY (device == NULL))
         {
+          g_object_get (G_OBJECT (view->preferences), "misc-show-delete-action", &show_delete_action, NULL);
+
           /* determine the parent file (required to determine "Delete" sensitivity) */
           parent_file = thunar_file_get_parent (file, NULL);
 
@@ -1462,8 +1476,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
           gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
           gtk_widget_show (item);
 
-          if (thunar_g_vfs_is_uri_scheme_supported ("trash")
-              && thunar_file_can_be_trashed (file))
+          if (thunar_g_vfs_is_uri_scheme_supported ("trash"))
             {
               /* append the "Move to Tash" menu action */
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
@@ -1471,30 +1484,34 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 G_GNUC_END_IGNORE_DEPRECATIONS
               g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_tree_view_action_move_to_trash), view);
               gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-              gtk_widget_set_sensitive (item, (parent_file != NULL && thunar_file_is_writable (parent_file)));
+              gtk_widget_set_sensitive (item, (parent_file != NULL && thunar_file_is_writable (parent_file) && thunar_file_can_be_trashed (file)));
               gtk_widget_show (item);
 
               /* set the icon */
-              image = gtk_image_new_from_icon_name ("user-trash-full", GTK_ICON_SIZE_MENU);
+              image = gtk_image_new_from_icon_name ("user-trash", GTK_ICON_SIZE_MENU);
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
               gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
 G_GNUC_END_IGNORE_DEPRECATIONS
             }
 
-          /* append the "Delete" menu action */
+          if (!thunar_g_vfs_is_uri_scheme_supported ("trash")
+              || show_delete_action || thunar_file_is_trashed (file))
+            {
+              /* append the "Delete" menu action */
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-          item = gtk_image_menu_item_new_with_mnemonic (_("_Delete"));
+              item = gtk_image_menu_item_new_with_mnemonic (_("_Delete"));
 G_GNUC_END_IGNORE_DEPRECATIONS
-          g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_tree_view_action_delete), view);
-          gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-          gtk_widget_set_sensitive (item, (parent_file != NULL && thunar_file_is_writable (parent_file)));
-          gtk_widget_show (item);
+              g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_tree_view_action_delete), view);
+              gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+              gtk_widget_set_sensitive (item, (parent_file != NULL && thunar_file_is_writable (parent_file)));
+              gtk_widget_show (item);
 
-          /* set the icon */
-          image = gtk_image_new_from_icon_name ("edit-delete", GTK_ICON_SIZE_MENU);
+              /* set the icon */
+              image = gtk_image_new_from_icon_name ("edit-delete", GTK_ICON_SIZE_MENU);
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-          gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+              gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
 G_GNUC_END_IGNORE_DEPRECATIONS
+            }
 
           /* cleanup */
           if (G_LIKELY (parent_file != NULL))
@@ -1814,13 +1831,12 @@ thunar_tree_view_action_cut (ThunarTreeView *view)
 
 
 static void
-thunar_tree_view_action_move_to_trash (ThunarTreeView *view)
+thunar_tree_view_action_unlink_selected_folder (ThunarTreeView *view,
+                                                gboolean        permanently)
 {
   ThunarApplication *application;
   ThunarFile        *file;
   GList              file_list;
-  gboolean           permanently;
-  GdkModifierType    state;
 
   _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view));
 
@@ -1828,18 +1844,18 @@ thunar_tree_view_action_move_to_trash (ThunarTreeView *view)
   file = thunar_tree_view_get_selected_file (view);
   if (G_LIKELY (file != NULL))
     {
-      /* fake a file list */
-      file_list.data = file;
-      file_list.next = NULL;
-      file_list.prev = NULL;
-
-      /* check if we should permanently delete the files (user holds shift) */
-      permanently = (gtk_get_current_event_state (&state) && (state & GDK_SHIFT_MASK) != 0);
-
-      /* delete the file */
-      application = thunar_application_get ();
-      thunar_application_unlink_files (application, GTK_WIDGET (view), &file_list, permanently);
-      g_object_unref (G_OBJECT (application));
+      if (thunar_file_can_be_trashed (file))
+        {
+          /* fake a file list */
+          file_list.data = file;
+          file_list.next = NULL;
+          file_list.prev = NULL;
+
+          /* delete the file */
+          application = thunar_application_get ();
+          thunar_application_unlink_files (application, GTK_WIDGET (view), &file_list, permanently);
+          g_object_unref (G_OBJECT (application));
+        }
 
       /* release the file */
       g_object_unref (G_OBJECT (file));
@@ -1849,31 +1865,17 @@ thunar_tree_view_action_move_to_trash (ThunarTreeView *view)
 
 
 static void
-thunar_tree_view_action_delete (ThunarTreeView *view)
+thunar_tree_view_action_move_to_trash (ThunarTreeView *view)
 {
-  ThunarApplication *application;
-  ThunarFile        *file;
-  GList              file_list;
+  thunar_tree_view_action_unlink_selected_folder (view, FALSE);
+}
 
-  _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view));
 
-  /* determine the selected file */
-  file = thunar_tree_view_get_selected_file (view);
-  if (G_LIKELY (file != NULL))
-    {
-      /* fake a file list */
-      file_list.data = file;
-      file_list.next = NULL;
-      file_list.prev = NULL;
 
-      /* delete the file */
-      application = thunar_application_get ();
-      thunar_application_unlink_files (application, GTK_WIDGET (view), &file_list, TRUE);
-      g_object_unref (G_OBJECT (application));
-
-      /* release the file */
-      g_object_unref (G_OBJECT (file));
-    }
+static void
+thunar_tree_view_action_delete (ThunarTreeView *view)
+{
+  thunar_tree_view_action_unlink_selected_folder (view, TRUE);
 }
 
 
@@ -2096,7 +2098,7 @@ thunar_tree_view_mount_finish (ThunarDevice *device,
       thunar_dialogs_show_error (GTK_WIDGET (data->view), error, _("Failed to mount \"%s\""), device_name);
       g_free (device_name);
     }
-  else
+  else if (thunar_device_is_mounted (device))
     {
       if (G_LIKELY (data->open_after_mounting))
         {
@@ -2501,11 +2503,11 @@ thunar_tree_view_cursor_idle (gpointer user_data)
   GtkTreePath    *path;
   GtkTreeIter     iter;
   ThunarFile     *file;
-  ThunarFile     *parent;
-  GFileInfo      *parent_info;
+  ThunarFolder   *folder;
+  GFileInfo      *file_info;
   GtkTreeIter     child_iter;
   ThunarFile     *file_in_tree;
-  gboolean        done = TRUE;
+  gboolean        done = FALSE;
   GList          *lp;
   GList          *path_as_list = NULL;
 
@@ -2517,12 +2519,12 @@ THUNAR_THREADS_ENTER
       gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), view->select_path, NULL, FALSE);
       gtk_tree_path_free (view->select_path);
       view->select_path = NULL;
-      return done;
+      return TRUE;
     }
 
   /* verify that we still have a current directory */
   if (G_UNLIKELY (view->current_directory == NULL))
-    return done;
+    return TRUE;
 
   /* get the preferred toplevel path for the current directory */
   path = thunar_tree_view_get_preferred_toplevel_path (view, view->current_directory);
@@ -2538,63 +2540,85 @@ THUNAR_THREADS_ENTER
   for (file = view->current_directory; file != NULL; file = thunar_file_get_parent (file, NULL))
       path_as_list = g_list_prepend (path_as_list, file);
 
-  /* note that iter may start at e.g. $HOME where "path_as_list" usually starts at "/" */
-  /* So the first few iterations most times will do nothing */
+  /* 1. skip files on path_as_list till we found the beginning of the tree (which e.g. may start at $HOME */
+  gtk_tree_model_get (GTK_TREE_MODEL (view->model), &iter, THUNAR_TREE_MODEL_COLUMN_FILE, &file_in_tree, -1);
   for (lp = path_as_list; lp != NULL; lp = lp->next)
+    {
+      if (THUNAR_FILE (lp->data) == file_in_tree)
+          break;
+    }
+  if (file_in_tree)
+    g_object_unref (file_in_tree);
+
+  /* 2. loop on the remaining path_as_list */
+  for (; lp != NULL; lp = lp->next)
     {
       file = THUNAR_FILE (lp->data);
 
-      /* check if iter has only a dummy node (tree not fully loaded yet) */
-      if( thunar_tree_model_node_has_dummy (view->model, iter.user_data) )
+      /* 3. Check if the contents of the corresponding folder is still being loaded */
+      folder = thunar_folder_get_for_file (file);
+      if (folder != NULL && thunar_folder_get_loading (folder))
+        {
+          g_object_unref (folder);
+          break;
+        }
+      if (folder)
+        g_object_unref (folder);
+
+      /* 4. Loop on all items of current tree-level to see if any folder matches the path we search */
+      while (TRUE)
+        {
+          gtk_tree_model_get (GTK_TREE_MODEL (view->model), &iter, THUNAR_TREE_MODEL_COLUMN_FILE, &file_in_tree, -1);
+          if (file == file_in_tree)
+            {
+              g_object_unref (file_in_tree);
+              break;
+            }
+          if (file_in_tree)
+            g_object_unref (file_in_tree);
+
+          if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (view->model), &iter))
+            break;
+        }
+
+      /* 5. Did we already find the full path ?*/
+      if (lp->next == NULL)
         {
-          done = FALSE;
+          path = gtk_tree_model_get_path (GTK_TREE_MODEL (view->model), &iter);
+          gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
+          gtk_tree_path_free (path);
+          done = TRUE;
           break;
         }
 
-      /* Try to create missing children if there are none (this as well initializes child_iter if there are children) */
+      /* 6. Get all children of the current tree iter */
+      /* Try to create missing children on the tree if there are none */
       if (!gtk_tree_model_iter_children (GTK_TREE_MODEL (view->model), &child_iter, &iter))
         {
-          done = FALSE;
-          parent = thunar_file_get_parent (file, NULL);
-          if (parent == NULL) /* e.g root has no parent .. skip it */
+          if (file == NULL) /* e.g root has no parent .. skip it */
             continue;
 
-          parent_info = thunar_file_get_info (parent);
-          if (parent_info != NULL)
+          file_info = thunar_file_get_info (file);
+          if (file_info != NULL)
             {
               /* E.g. folders for which we do not have read permission dont have any child in the tree */
               /* Make sure that missing read permissions are the problem */
-              if (!g_file_info_get_attribute_boolean (parent_info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ))
+              if (!g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ))
                 {
                   /* We KNOW that there is a File. Lets just create the required tree-node */
-                  thunar_tree_model_add_child (view->model, iter.user_data, file);
+                  thunar_tree_model_add_child (view->model, iter.user_data,  THUNAR_FILE (lp->next->data));
                 }
             }
-          g_object_unref (parent);
           break; /* we dont have a valid child_iter by now, so we cannot continue.                         */
                  /* Since done is FALSE, the next iteration on thunar_tree_view_cursor_idle will go deeper */
         }
 
-      /* loop on children to see if any folder matches  */
-      while (TRUE)
-        {
-          gtk_tree_model_get (GTK_TREE_MODEL (view->model), &child_iter, THUNAR_TREE_MODEL_COLUMN_FILE, &file_in_tree, -1);
-          if (file == file_in_tree)
-            {
-              g_object_unref (file_in_tree);
-              path = gtk_tree_model_get_path (GTK_TREE_MODEL (view->model), &child_iter);
-              gtk_tree_view_expand_to_path (GTK_TREE_VIEW (view), path);
-              gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
-              gtk_tree_path_free (path);
-              iter = child_iter; /* next tree level */
-              break;
-            }
-          if (file_in_tree)
-            g_object_unref (file_in_tree);
+      /* expand path up to the current tree level */
+      path = gtk_tree_model_get_path (GTK_TREE_MODEL (view->model), &iter);
+      gtk_tree_view_expand_to_path (GTK_TREE_VIEW (view), path);
+      gtk_tree_path_free (path);
 
-          if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (view->model), &child_iter))
-            break;
-        }
+      iter = child_iter; /* next tree level */
     }
 
   /* tidy up */
@@ -2849,8 +2873,8 @@ thunar_tree_view_set_show_hidden (ThunarTreeView *view,
  *
  * Searches for the best-matching toplevel path in the
  * following order:
- *   1) any mounted device or network resource
- *   2) the user's desktop directory
+ *   1) the currently active one
+ *   2) any mounted device or network resource
  *   3) the user's home directory
  *   4) the root filesystem
  *
@@ -2872,6 +2896,35 @@ thunar_tree_view_get_preferred_toplevel_path (ThunarTreeView *view,
 
   _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
 
+  /* get active toplevel path and check if we can use it */
+  gtk_tree_view_get_cursor (GTK_TREE_VIEW (view), &path, NULL);
+  if (path != NULL)
+    {
+      if (gtk_tree_path_get_depth (path) != 1)
+        while (gtk_tree_path_get_depth (path) > 1)
+          gtk_tree_path_up (path);
+
+      if (gtk_tree_model_get_iter (GTK_TREE_MODEL (view->model), &iter, path))
+        {
+          /* lookup file for the toplevel item */
+          gtk_tree_model_get (GTK_TREE_MODEL (view->model), &iter, THUNAR_TREE_MODEL_COLUMN_FILE, &toplevel_file, -1);
+          if (toplevel_file)
+            {
+              /* check if the toplevel file is an ancestor */
+              if (thunar_file_is_ancestor (file, toplevel_file))
+                {
+                  g_object_unref (toplevel_file);
+                  return path;
+                }
+
+              g_object_unref (toplevel_file);
+            }
+        }
+
+      gtk_tree_path_free (path);
+      path = NULL;
+    }
+
   /* check whether the root node is available */
   if (!gtk_tree_model_get_iter_first (model, &iter))
     return NULL;
diff --git a/thunar/thunar-user.c b/thunar/thunar-user.c
index ceba7b0d..3fef90cf 100644
--- a/thunar/thunar-user.c
+++ b/thunar/thunar-user.c
@@ -562,10 +562,14 @@ thunar_user_manager_flush_timer (gpointer user_data)
 THUNAR_THREADS_ENTER
 
   /* drop all cached groups */
-  size += g_hash_table_foreach_remove (manager->groups, (GHRFunc) gtk_true, NULL);
+  size += g_hash_table_foreach_remove (manager->groups,
+                                       (GHRFunc) (void (*)(void)) gtk_true,
+                                       NULL);
 
   /* drop all cached users */
-  size += g_hash_table_foreach_remove (manager->users, (GHRFunc) gtk_true, NULL);
+  size += g_hash_table_foreach_remove (manager->users,
+                                       (GHRFunc) (void (*)(void)) gtk_true,
+                                       NULL);
 
   /* reload groups and passwd files if we had cached entities */
   if (G_LIKELY (size > 0))
diff --git a/thunar/thunar-util.c b/thunar/thunar-util.c
index c3c864a7..99cd4786 100644
--- a/thunar/thunar-util.c
+++ b/thunar/thunar-util.c
@@ -374,7 +374,7 @@ thunar_util_humanize_file_time (guint64          file_time,
                                 const gchar     *date_custom_style)
 {
   const gchar *date_format;
-  struct tm   *tfile;
+  struct tm    tfile;
   time_t       ftime;
   GDate        dfile;
   GDate        dnow;
@@ -385,8 +385,8 @@ thunar_util_humanize_file_time (guint64          file_time,
     {
       ftime = (time_t) file_time;
 
-      /* determine the local file time */
-      tfile = localtime (&ftime);
+      /* take a copy of the local file time */
+      tfile = *localtime (&ftime);
 
       /* check which style to use to format the time */
       if (date_style == THUNAR_DATE_STYLE_SIMPLE || date_style == THUNAR_DATE_STYLE_SHORT)
@@ -407,7 +407,7 @@ thunar_util_humanize_file_time (guint64          file_time,
               else /* if (date_style == THUNAR_DATE_STYLE_SHORT) */
                 {
                   /* TRANSLATORS: file was modified less than one day ago */
-                  return exo_strdup_strftime (_("Today at %X"), tfile);
+                  return exo_strdup_strftime (_("Today at %X"), &tfile);
                 }
             }
           else if (diff == 1)
@@ -420,7 +420,7 @@ thunar_util_humanize_file_time (guint64          file_time,
               else /* if (date_style == THUNAR_DATE_STYLE_SHORT) */
                 {
                   /* TRANSLATORS: file was modified less than two days ago */
-                  return exo_strdup_strftime (_("Yesterday at %X"), tfile);
+                  return exo_strdup_strftime (_("Yesterday at %X"), &tfile);
                 }
             }
           else
@@ -437,25 +437,25 @@ thunar_util_humanize_file_time (guint64          file_time,
                 }
 
               /* format the date string accordingly */
-              return exo_strdup_strftime (date_format, tfile);
+              return exo_strdup_strftime (date_format, &tfile);
             }
         }
       else if (date_style == THUNAR_DATE_STYLE_LONG)
         {
           /* use long, date(1)-like format string */
-          return exo_strdup_strftime ("%c", tfile);
+          return exo_strdup_strftime ("%c", &tfile);
         }
       else if (date_style == THUNAR_DATE_STYLE_YYYYMMDD)
         {
-          return exo_strdup_strftime ("%Y-%m-%d %H:%M:%S", tfile);
+          return exo_strdup_strftime ("%Y-%m-%d %H:%M:%S", &tfile);
         }
       else if (date_style == THUNAR_DATE_STYLE_MMDDYYYY)
         {
-          return exo_strdup_strftime ("%m-%d-%Y %H:%M:%S", tfile);
+          return exo_strdup_strftime ("%m-%d-%Y %H:%M:%S", &tfile);
         }
       else if (date_style == THUNAR_DATE_STYLE_DDMMYYYY)
         {
-          return exo_strdup_strftime ("%d-%m-%Y %H:%M:%S", tfile);
+          return exo_strdup_strftime ("%d-%m-%Y %H:%M:%S", &tfile);
         }
       else /* if (date_style == THUNAR_DATE_STYLE_CUSTOM) */
         {
@@ -463,7 +463,7 @@ thunar_util_humanize_file_time (guint64          file_time,
             return g_strdup ("");
 
           /* use custom date formatting */
-          return exo_strdup_strftime (date_custom_style, tfile);
+          return exo_strdup_strftime (date_custom_style, &tfile);
         }
     }
 
diff --git a/thunar/thunar-view.c b/thunar/thunar-view.c
index 698d6872..d2a15616 100644
--- a/thunar/thunar-view.c
+++ b/thunar/thunar-view.c
@@ -41,7 +41,7 @@ thunar_view_get_type (void)
       type = g_type_register_static_simple (G_TYPE_INTERFACE,
                                             I_("ThunarView"),
                                             sizeof (ThunarViewIface),
-                                            (GClassInitFunc) thunar_view_class_init,
+                                            (GClassInitFunc) (void (*)(void)) thunar_view_class_init,
                                             0,
                                             NULL,
                                             0);
diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c
index df24b900..9e9be0fd 100644
--- a/thunar/thunar-window.c
+++ b/thunar/thunar-window.c
@@ -216,6 +216,9 @@ static void     thunar_window_action_about                (GtkAction
                                                            ThunarWindow           *window);
 static void     thunar_window_action_show_hidden          (GtkToggleAction        *action,
                                                            ThunarWindow           *window);
+static gboolean thunar_window_propagate_key_event         (GtkWindow              *window,
+                                                           GdkEvent               *key_event,
+                                                           gpointer               user_data);
 static void     thunar_window_current_directory_changed   (ThunarFile             *current_directory,
                                                            ThunarWindow           *window);
 static void     thunar_window_connect_proxy               (GtkUIManager           *manager,
@@ -377,6 +380,7 @@ static GtkActionEntry action_entries[] =
   { "open-network", "network-workgroup", N_("B_rowse Network"), NULL, N_ ("Browse local network connections"), G_CALLBACK (thunar_window_action_open_network), },
   { "open-templates", "text-x-generic-template", N_("T_emplates"), NULL, N_ ("Go to the templates folder"), G_CALLBACK (thunar_window_action_open_templates), },
   { "open-location", NULL, N_ ("_Open Location..."), "<control>L", N_ ("Specify a location to open"), G_CALLBACK (thunar_window_action_open_location), },
+  { "open-location-alt", NULL, "open-location-alt", "<alt>D", NULL, G_CALLBACK (thunar_window_action_open_location), },
   { "help-menu", NULL, N_ ("_Help"), NULL, },
   { "contents", "help-browser", N_ ("_Contents"), "F1", N_ ("Display Thunar user manual"), G_CALLBACK (thunar_window_action_contents), },
   { "about", "help-about", N_ ("_About"), NULL, N_ ("Display information about Thunar"), G_CALLBACK (thunar_window_action_about), },
@@ -651,7 +655,7 @@ static inline gint
 view_type2index (GType type)
 {
   /* this necessary for platforms where sizeof(GType) != sizeof(gint),
-   * see http://bugzilla.xfce.org/show_bug.cgi?id=2726 for details.
+   * see https://bugzilla.xfce.org/show_bug.cgi?id=2726 for details.
    */
   if (sizeof (GType) == sizeof (gint))
     {
@@ -676,7 +680,7 @@ static inline GType
 view_index2type (gint idx)
 {
   /* this necessary for platforms where sizeof(GType) != sizeof(gint),
-   * see http://bugzilla.xfce.org/show_bug.cgi?id=2726 for details.
+   * see https://bugzilla.xfce.org/show_bug.cgi?id=2726 for details.
    */
   if (sizeof (GType) == sizeof (gint))
     {
@@ -761,6 +765,10 @@ thunar_window_init (ThunarWindow *window)
   g_closure_sink (window->menu_item_deselected_closure);
   window->icon_factory = thunar_icon_factory_get_default ();
 
+  /* Catch key events before accelerators get processed */
+  g_signal_connect (window, "key-press-event", G_CALLBACK (thunar_window_propagate_key_event), NULL);
+  g_signal_connect (window, "key-release-event", G_CALLBACK (thunar_window_propagate_key_event), NULL);
+
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   /* setup the action group for this window */
   window->action_group = gtk_action_group_new ("ThunarWindow");
@@ -1428,10 +1436,13 @@ thunar_window_unrealize (GtkWidget *widget)
 
   /* disconnect from the clipboard manager */
   g_signal_handlers_disconnect_by_func (G_OBJECT (window->clipboard), gtk_widget_queue_draw, widget);
-  g_object_unref (G_OBJECT (window->clipboard));
 
   /* let the GtkWidget class unrealize the window */
   (*GTK_WIDGET_CLASS (thunar_window_parent_class)->unrealize) (widget);
+
+  /* drop the reference on the clipboard manager, we do this after letting the GtkWidget class
+   * unrealise the window to prevent the clipboard being disposed during the unrealize  */
+  g_object_unref (G_OBJECT (window->clipboard));
 }
 
 
@@ -3234,6 +3245,31 @@ G_GNUC_END_IGNORE_DEPRECATIONS
 
 
 
+static gboolean
+thunar_window_propagate_key_event (GtkWindow* window,
+                                   GdkEvent  *key_event,
+                                   gpointer   user_data)
+{
+  GtkWidget* focused_widget;
+
+  _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), GDK_EVENT_PROPAGATE);
+
+  focused_widget = gtk_window_get_focus (window);
+
+  /* Turn the accelerator priority around globally,
+   * so that the focused widget always gets the accels first.
+   * Implementing this cleanly while maintaining some wanted accels
+   * (like Ctrl+N and exo accels) is a lot of work. So we resort to
+   * only priorize GtkEditable, because that is the easiest way to
+   * fix the right-ahead problem. */
+  if (focused_widget != NULL && GTK_IS_EDITABLE (focused_widget))
+    return gtk_window_propagate_key_event (window, (GdkEventKey *) key_event);
+
+  return GDK_EVENT_PROPAGATE;
+}
+
+
+
 static void
 thunar_window_poke_location_finish (ThunarBrowser *browser,
                                     GFile         *location,
@@ -3619,7 +3655,8 @@ thunar_window_device_pre_unmount (ThunarDeviceMonitor *device_monitor,
     return;
 
   /* check if the file is the current directory or an ancestor of the current directory */
-  if (thunar_file_is_gfile_ancestor (window->current_directory, root_file))
+  if (g_file_equal (thunar_file_get_file (window->current_directory), root_file)
+      || thunar_file_is_gfile_ancestor (window->current_directory, root_file))
     {
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
       /* change to the home folder */
diff --git a/thunarx/thunarx-file-info.c b/thunarx/thunarx-file-info.c
index ae9f184e..ad832062 100644
--- a/thunarx/thunarx-file-info.c
+++ b/thunarx/thunarx-file-info.c
@@ -427,12 +427,12 @@ GList*
 thunarx_file_info_list_copy (GList *file_infos)
 {
 #if GLIB_CHECK_VERSION (2, 34, 0)
-  return g_list_copy_deep (file_infos, (GCopyFunc) g_object_ref, NULL);
+  return g_list_copy_deep (file_infos, (GCopyFunc) (void (*)(void)) g_object_ref, NULL);
 #else
   GList *copy;
 
   copy = g_list_copy (file_infos);
-  g_list_foreach (copy, (GFunc) g_object_ref, NULL);
+  g_list_foreach (copy, (GFunc) (void (*)(void)) g_object_ref, NULL);
 
   return copy;
 #endif
diff --git a/thunarx/thunarx-menu-item.c b/thunarx/thunarx-menu-item.c
index d9a518c9..4969a6e7 100644
--- a/thunarx/thunarx-menu-item.c
+++ b/thunarx/thunarx-menu-item.c
@@ -27,8 +27,6 @@
 
 
 
-#define THUNARX_MENU_ITEM_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNARX_TYPE_MENU_ITEM, ThunarxMenuItemPrivate))
-
 /**
  * SECTION: thunarx-menu-item
  * @short_description: The base class for menu items added to the context menus
@@ -93,7 +91,7 @@ static guint signals[LAST_SIGNAL];
 
 
 
-G_DEFINE_TYPE (ThunarxMenuItem, thunarx_menu_item, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_PRIVATE (ThunarxMenuItem, thunarx_menu_item, G_TYPE_OBJECT)
 
 
 
@@ -102,9 +100,6 @@ thunarx_menu_item_class_init (ThunarxMenuItemClass *klass)
 {
   GObjectClass *gobject_class;
 
-  /* add our private data to the class type */
-  g_type_class_add_private (klass, sizeof (ThunarxMenuItemPrivate));
-
   gobject_class = G_OBJECT_CLASS (klass);
   gobject_class->finalize = thunarx_menu_item_finalize;
   gobject_class->get_property = thunarx_menu_item_get_property;
@@ -177,7 +172,7 @@ thunarx_menu_item_class_init (ThunarxMenuItemClass *klass)
 static void
 thunarx_menu_item_init (ThunarxMenuItem *item)
 {
-  item->priv = THUNARX_MENU_ITEM_GET_PRIVATE (item);
+  item->priv = thunarx_menu_item_get_instance_private (item);
   item->priv->sensitive = TRUE;
   item->priv->priority = FALSE;
   item->priv->menu = NULL;
@@ -414,6 +409,6 @@ thunarx_menu_item_list_free (GList *items)
 {
   g_return_if_fail (items != NULL);
 
-  g_list_foreach (items, (GFunc)g_object_unref, NULL);
+  g_list_foreach (items, (GFunc) (void (*)(void)) g_object_unref, NULL);
   g_list_free (items);
 }
diff --git a/thunarx/thunarx-menu.c b/thunarx/thunarx-menu.c
index 97961b59..87c431a4 100644
--- a/thunarx/thunarx-menu.c
+++ b/thunarx/thunarx-menu.c
@@ -27,8 +27,6 @@
 
 
 
-#define THUNARX_MENU_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNARX_TYPE_MENU, ThunarxMenuPrivate))
-
 /**
  * SECTION: thunarx-menu
  * @short_description: The base class for submenus added to the context menus
@@ -53,7 +51,7 @@ struct _ThunarxMenuPrivate
 
 
 
-G_DEFINE_TYPE (ThunarxMenu, thunarx_menu, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_PRIVATE (ThunarxMenu, thunarx_menu, G_TYPE_OBJECT)
 
 
 
@@ -62,9 +60,6 @@ thunarx_menu_class_init (ThunarxMenuClass *klass)
 {
   GObjectClass *gobject_class;
 
-  /* add our private data to the class type */
-  g_type_class_add_private (klass, sizeof (ThunarxMenuPrivate));
-
   gobject_class = G_OBJECT_CLASS (klass);
   gobject_class->finalize = thunarx_menu_finalize;
 }
@@ -74,7 +69,7 @@ thunarx_menu_class_init (ThunarxMenuClass *klass)
 static void
 thunarx_menu_init (ThunarxMenu *menu)
 {
-  menu->priv = THUNARX_MENU_GET_PRIVATE (menu);
+  menu->priv = thunarx_menu_get_instance_private (menu);
   menu->priv->items = NULL;
 }
 
@@ -138,7 +133,7 @@ thunarx_menu_get_items (ThunarxMenu *menu)
   g_return_val_if_fail (menu != NULL, NULL);
 
   items = g_list_copy (menu->priv->items);
-  g_list_foreach (items, (GFunc) g_object_ref, NULL);
+  g_list_foreach (items, (GFunc) (void (*)(void)) g_object_ref, NULL);
 
   return items;
 }
diff --git a/thunarx/thunarx-property-page.c b/thunarx/thunarx-property-page.c
index 97bf5fc3..952c5903 100644
--- a/thunarx/thunarx-property-page.c
+++ b/thunarx/thunarx-property-page.c
@@ -29,8 +29,6 @@
 
 
 
-#define THUNARX_PROPERTY_PAGE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNARX_TYPE_PROPERTY_PAGE, ThunarxPropertyPagePrivate))
-
 /**
  * SECTION: thunarx-property-page
  * @short_description: The base class for pages added to the properties dialog
@@ -85,7 +83,7 @@ struct _ThunarxPropertyPagePrivate
 
 
 
-G_DEFINE_TYPE (ThunarxPropertyPage, thunarx_property_page, GTK_TYPE_BIN)
+G_DEFINE_TYPE_WITH_PRIVATE (ThunarxPropertyPage, thunarx_property_page, GTK_TYPE_BIN)
 
 
 
@@ -95,9 +93,6 @@ thunarx_property_page_class_init (ThunarxPropertyPageClass *klass)
   GtkWidgetClass *gtkwidget_class;
   GObjectClass   *gobject_class;
 
-  /* add our private data to the class type */
-  g_type_class_add_private (klass, sizeof (ThunarxPropertyPagePrivate));
-
   gobject_class = G_OBJECT_CLASS (klass);
   gobject_class->get_property = thunarx_property_page_get_property;
   gobject_class->set_property = thunarx_property_page_set_property;
@@ -137,7 +132,7 @@ thunarx_property_page_class_init (ThunarxPropertyPageClass *klass)
 static void
 thunarx_property_page_init (ThunarxPropertyPage *property_page)
 {
-  property_page->priv = THUNARX_PROPERTY_PAGE_GET_PRIVATE (property_page);
+  property_page->priv = thunarx_property_page_get_instance_private (property_page);
 }
 
 
diff --git a/thunarx/thunarx-provider-plugin.c b/thunarx/thunarx-provider-plugin.c
index a1d3abfb..ef2a197f 100644
--- a/thunarx/thunarx-provider-plugin.c
+++ b/thunarx/thunarx-provider-plugin.c
@@ -53,7 +53,7 @@ thunarx_provider_plugin_get_type (void)
       type = g_type_register_static_simple (G_TYPE_INTERFACE,
                                             I_("ThunarxProviderPlugin"),
                                             sizeof (ThunarxProviderPluginIface),
-                                            (GClassInitFunc) thunarx_provider_plugin_class_init,
+                                            (GClassInitFunc) (void (*)(void)) thunarx_provider_plugin_class_init,
                                             0,
                                             NULL,
                                             0);
diff --git a/thunarx/thunarx-renamer.c b/thunarx/thunarx-renamer.c
index 715dbd39..34094e0e 100644
--- a/thunarx/thunarx-renamer.c
+++ b/thunarx/thunarx-renamer.c
@@ -29,10 +29,6 @@
 
 
 
-#define THUNARX_RENAMER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNARX_TYPE_RENAMER, ThunarxRenamerPrivate))
-
-
-
 /* Property identifiers */
 enum
 {
@@ -114,7 +110,7 @@ static guint renamer_signals[LAST_SIGNAL];
 
 
 
-G_DEFINE_ABSTRACT_TYPE (ThunarxRenamer, thunarx_renamer, GTK_TYPE_BOX)
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ThunarxRenamer, thunarx_renamer, GTK_TYPE_BOX)
 
 
 
@@ -123,9 +119,6 @@ thunarx_renamer_class_init (ThunarxRenamerClass *klass)
 {
   GObjectClass *gobject_class;
 
-  /* add private data */
-  g_type_class_add_private (klass, sizeof (ThunarxRenamerPrivate));
-
   gobject_class = G_OBJECT_CLASS (klass);
   gobject_class->finalize = thunarx_renamer_finalize;
   gobject_class->constructor = thunarx_renamer_constructor;
@@ -200,7 +193,7 @@ static void
 thunarx_renamer_init (ThunarxRenamer *renamer)
 {
   /* grab a pointer on the private data */
-  renamer->priv = THUNARX_RENAMER_GET_PRIVATE (renamer);
+  renamer->priv = thunarx_renamer_get_instance_private (renamer);
 
   /* initialize the GtkBox to sane defaults */
   gtk_orientable_set_orientation (GTK_ORIENTABLE (renamer), GTK_ORIENTATION_VERTICAL);
diff --git a/thunarx/thunarx.h b/thunarx/thunarx.h
index 192bf9a7..e0d6089a 100644
--- a/thunarx/thunarx.h
+++ b/thunarx/thunarx.h
@@ -69,12 +69,12 @@ type_name##_register_type (ThunarxProviderPlugin *thunarx_define_type_plugin) \
     sizeof (TypeName##Class), \
     NULL, \
     NULL, \
-    (GClassInitFunc) type_name##_class_intern_init, \
+    (GClassInitFunc) (void (*)(void)) type_name##_class_intern_init, \
     NULL, \
     NULL, \
     sizeof (TypeName), \
     0, \
-    (GInstanceInitFunc) type_name##_init, \
+    (GInstanceInitFunc) (void (*)(void)) type_name##_init, \
     NULL, \
   }; \
   thunarx_define_type_id = thunarx_provider_plugin_register_type (thunarx_define_type_plugin, TYPE_PARENT, \
@@ -87,7 +87,7 @@ type_name##_register_type (ThunarxProviderPlugin *thunarx_define_type_plugin) \
 { \
   static const GInterfaceInfo thunarx_implement_interface_info = \
   { \
-    (GInterfaceInitFunc) iface_init \
+    .interface_init = (GInterfaceInitFunc) (void (*)(void)) iface_init \
   }; \
   thunarx_provider_plugin_add_interface (thunarx_define_type_plugin, thunarx_define_type_id, TYPE_IFACE, &thunarx_implement_interface_info); \
 }

Reply to: