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

Bug#988850: marked as done (buster-pu: package thunar/1.8.17-1)



Your message dated Sat, 10 Sep 2022 19:15:09 +0100
with message-id <e5d0cf9f6b27f76f3bc7d0be2c87f554baa5dbad.camel@adam-barratt.org.uk>
and subject line Re: Bug#988850: buster-pu: package thunar/1.8.17-1
has caused the Debian Bug report #988850,
regarding buster-pu: package thunar/1.8.17-1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
988850: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=988850
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
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); \
 }

--- End Message ---
--- Begin Message ---
On Fri, 2022-08-05 at 20:15 +0100, Adam D. Barratt wrote:
> On Thu, 2021-05-20 at 15:25 +0200, Yves-Alexis Perez wrote:
> > 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.
> > 
> 
> Apologies for the long delay in this getting a response.
> 
> We're in the process of preparing the final point release for buster,
> as support transitions over to the LTS team.

That final point release has now happened, so I'm afraid I'm going to
close this request now; apologies for not dealing with it sooner.

Regards,

Adam

--- End Message ---

Reply to: