diff --git a/.gitignore b/.gitignore
index d95d64076138040af92fdc7fc1595727a0f6320c..33e74eb7c17c19cb377283e2767f518a3191930e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,6 +66,8 @@ src/*-enum-types.*
 src/xfdesktop
 src/xfdesktop-marshal.c
 src/xfdesktop-marshal.h
+src/xfdesktop-monitor-chooser-ui.c
+src/xfdesktop-monitor-chooser-ui.h
 src/xfdesktop-file-manager-fdo-proxy.c
 src/xfdesktop-file-manager-fdo-proxy.h
 src/xfdesktop-file-manager-proxy.c
diff --git a/common/xfdesktop-marshal.list b/common/xfdesktop-marshal.list
index 814b937108ec7a5169c6fd9ed97316b666fb9d64..92f4ede3f2ebc9613049c2c16012c3148761432b 100644
--- a/common/xfdesktop-marshal.list
+++ b/common/xfdesktop-marshal.list
@@ -2,7 +2,7 @@ BOOLEAN:BOXED,INT,INT,BOOLEAN,OBJECT
 BOOLEAN:ENUM,INT
 BOOLEAN:OBJECT,BOXED,INT,INT,UINT
 BOOLEAN:OBJECT,BOXED,POINTER,FLAGS
-BOOLEAN:OBJECT,POINTER,POINTER
+OBJECT:OBJECT,POINTER,POINTER
 BOOLEAN:VOID
 FLAGS:BOXED
 FLAGS:BOXED,POINTER
diff --git a/src/Makefile.am b/src/Makefile.am
index cf1d94d7e7e2e0bc37b5e9c74cc56c422da52167..a1ae68afee072518464e070bf590c3d4fa42a1fd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -154,6 +154,10 @@ xfdesktop_SOURCES += $(desktop_icon_sources)
 
 if ENABLE_FILE_ICONS
 
+xfdesktop_built_sources += \
+	xfdesktop-monitor-chooser-ui.c \
+	xfdesktop-monitor-chooser-ui.h
+
 xfdesktop_SOURCES += $(desktop_file_icon_sources)
 
 xfdesktop_CFLAGS += \
@@ -165,6 +169,9 @@ xfdesktop_LDADD += \
 endif
 endif
 
+glade_files = \
+	xfdesktop-monitor-chooser-ui.glade
+
 BUILT_SOURCES = \
 	$(xfdesktop_built_sources)
 
@@ -174,6 +181,7 @@ DISTCLEANFILES = \
 EXTRA_DIST = \
 	$(desktop_icon_sources) \
 	$(desktop_file_icon_sources) \
+	$(glade_files) \
 	xfdesktop-file-manager-fdo-dbus.xml \
 	xfdesktop-file-manager-dbus.xml \
 	xfdesktop-thunar-dbus.xml \
@@ -206,3 +214,9 @@ xfdesktop-trash-proxy.c xfdesktop-trash-proxy.h : $(srcdir)/xfdesktop-trash-dbus
 		--interface-prefix=org.xfce. \
 		--generate-c-code=xfdesktop-trash-proxy \
 		$<
+
+%-ui.h: $(srcdir)/%-ui.gresource.xml $(glade_files) Makefile
+	$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate-header --manual-register $<
+
+%-ui.c: $(srcdir)/%-ui.gresource.xml $(glade_files) Makefile
+	$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate-source --manual-register $<
diff --git a/src/main.c b/src/main.c
index 74b94322993f31db8362d7f6f03e6d4071a792f3..242f0649852c27f365162adaa700bba9cb66ffb4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -35,6 +35,10 @@
 
 #include "xfdesktop-application.h"
 
+#ifdef ENABLE_FILE_ICONS
+#include "xfdesktop-monitor-chooser-ui.h"
+#endif
+
 int
 main(int argc, char **argv)
 {
@@ -50,6 +54,10 @@ main(int argc, char **argv)
     /* bind gettext textdomain */
     xfce_textdomain(GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
 
+#ifdef ENABLE_DESKTOP_ICONS
+    xfdesktop_monitor_chooser_ui_register_resource();
+#endif
+
     app = xfdesktop_application_get();
     g_application_add_option_group(G_APPLICATION(app), xfce_sm_client_get_option_group(argc, argv));
 
diff --git a/src/meson.build b/src/meson.build
index 57a403bab3059012942b303b64d043ed56b40879..f51889b35ca13a4ee6f724e4bcd4e25d4ec711cb 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -60,6 +60,15 @@ if enable_file_icons
     'xfdesktop-special-file-icon.c',
     'xfdesktop-volume-icon.c',
   ]
+
+  xfdesktop_sources += gnome.compile_resources(
+    'xfdesktop-monitor-chooser-ui',
+    'xfdesktop-monitor-chooser-ui.gresource.xml',
+    export: false,
+    extra_args: [
+      '--manual-register',
+      ],
+    )
 endif
 
 if enable_libnotify
diff --git a/src/xfdesktop-file-icon-manager.c b/src/xfdesktop-file-icon-manager.c
index 40deced01ac218dc68eb8e2d1584bcb977815a8a..defb41a11ca0696624936554b8c77866f3369d35 100644
--- a/src/xfdesktop-file-icon-manager.c
+++ b/src/xfdesktop-file-icon-manager.c
@@ -44,16 +44,15 @@
 #include <sys/types.h>
 #endif
 
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 
+#include <glib.h>
+#include <glib-object.h>
 #include <gio/gio.h>
 #include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
 
 #ifdef HAVE_THUNARX
 #include <thunarx/thunarx.h>
@@ -68,9 +67,11 @@
 #include "xfdesktop-file-icon-model.h"
 #include "xfdesktop-file-icon-model-filter.h"
 #include "xfdesktop-file-utils.h"
+#include "xfdesktop-icon-position-configs.h"
 #include "xfdesktop-icon-view-holder.h"
 #include "xfdesktop-icon-view.h"
 #include "xfdesktop-icon-view-model.h"
+#include "xfdesktop-icon.h"
 #include "xfdesktop-regular-file-icon.h"
 #include "xfdesktop-special-file-icon.h"
 #include "xfdesktop-volume-icon.h"
@@ -90,9 +91,9 @@ struct _XfdesktopFileIconManager
 
     gboolean ready;
 
-    XfdesktopIconViewHolder *holder;
     XfdesktopFileIconModel *model;
-    XfdesktopFileIconModelFilter *filter;
+    GHashTable *monitor_data;  // XfwMonitor (owner) -> MonitorData (owner)
+    XfdesktopIconPositionConfigs *position_configs;
 
     GdkScreen *gscreen;
     XfdesktopBackdropManager *backdrop_manager;
@@ -100,8 +101,6 @@ struct _XfdesktopFileIconManager
     GFile *folder;
     XfdesktopFileIcon *desktop_icon;
 
-    guint save_icons_id;
-
     GtkTargetList *drag_targets;
     GtkTargetList *drop_targets;
 
@@ -124,6 +123,25 @@ enum {
     PROP_MAX_TEMPLATES,
 };
 
+typedef struct {
+    XfdesktopFileIconManager *fmanager;
+    XfdesktopIconViewHolder *holder;
+    XfdesktopFileIconModelFilter *filter;
+    XfdesktopIconPositionConfig *position_config;
+} MonitorData;
+
+static void
+monitor_data_free(MonitorData *mdata) {
+    if (mdata->position_config != NULL) {
+        XfceDesktop *desktop = xfdesktop_icon_view_holder_get_desktop(mdata->holder);
+        XfwMonitor *monitor = xfce_desktop_get_monitor(desktop);
+        xfdesktop_icon_position_configs_unassign_monitor(mdata->fmanager->position_configs, monitor);
+    }
+    g_object_unref(mdata->holder);
+    g_object_unref(mdata->filter);
+    g_free(mdata);
+}
+
 static void xfdesktop_file_icon_manager_constructed(GObject *obj);
 static void xfdesktop_file_icon_manager_set_property(GObject *object,
                                                      guint property_id,
@@ -138,24 +156,24 @@ static void xfdesktop_file_icon_manager_finalize(GObject *obj);
 
 static GdkDragAction xfdesktop_file_icon_manager_drag_actions_get(XfdesktopIconView *icon_view,
                                                                   GtkTreeIter *iter,
-                                                                  XfdesktopFileIconManager *fmanager);
+                                                                  MonitorData *mdata);
 static GdkDragAction xfdesktop_file_icon_manager_drop_actions_get(XfdesktopIconView *icon_view,
                                                                   GtkTreeIter *iter,
                                                                   GdkDragAction *suggested_action,
-                                                                  XfdesktopFileIconManager *fmanager);
+                                                                  MonitorData *mdata);
 static gboolean xfdesktop_file_icon_manager_drag_drop_item(XfdesktopIconView *icon_view,
                                                            GdkDragContext *context,
                                                            GtkTreeIter *iter,
                                                            gint row,
                                                            gint col,
                                                            guint time_,
-                                                           XfdesktopFileIconManager *fmanager);
+                                                           MonitorData *mdata);
 static gboolean xfdesktop_file_icon_manager_drag_drop_items(XfdesktopIconView *icon_view,
                                                             GdkDragContext *context,
                                                             GtkTreeIter *iter,
                                                             GList *dropped_item_paths,
                                                             GdkDragAction action,
-                                                            XfdesktopFileIconManager *fmanager);
+                                                            MonitorData *mdata);
 static GdkDragAction xfdesktop_file_icon_manager_drag_drop_ask(XfdesktopIconView *icon_view,
                                                                GdkDragContext *context,
                                                                GtkTreeIter *iter,
@@ -171,20 +189,20 @@ static void xfdesktop_file_icon_manager_drag_item_data_received(XfdesktopIconVie
                                                                 GtkSelectionData *data,
                                                                 guint info,
                                                                 guint time_,
-                                                                XfdesktopFileIconManager *fmanager);
+                                                                MonitorData *mdata);
 static void xfdesktop_file_icon_manager_drag_data_get(GtkWidget *icon_view,
                                                       GdkDragContext *context,
                                                       GtkSelectionData *data,
                                                       guint info,
                                                       guint time_,
-                                                      XfdesktopFileIconManager *fmanager);
+                                                      MonitorData *mdata);
 static GdkDragAction xfdesktop_file_icon_manager_drop_propose_action(XfdesktopIconView *icon_view,
                                                                      GdkDragContext *context,
                                                                      GtkTreeIter *iter,
                                                                      GdkDragAction action,
                                                                      GtkSelectionData *data,
                                                                      guint info,
-                                                                     XfdesktopFileIconManager *fmanager);
+                                                                     MonitorData *mdata);
 
 static void xfdesktop_file_icon_manager_desktop_added(XfdesktopIconViewManager *manager,
                                                       XfceDesktop *desktop);
@@ -195,18 +213,13 @@ static GtkMenu *xfdesktop_file_icon_manager_get_context_menu(XfdesktopIconViewMa
 static void xfdesktop_file_icon_manager_sort_icons(XfdesktopIconViewManager *manager,
                                                    GtkSortType sort_type);
 
-static void xfdesktop_file_icon_manager_save_icons(XfdesktopFileIconManager *fmanager);
-
-static void create_icon_view(XfdesktopFileIconManager *fmanager,
-                             XfceDesktop *desktop);
-
 static void xfdesktop_file_icon_manager_icon_moved(XfdesktopIconView *icon_view,
                                                    GtkTreeIter *iter,
                                                    gint new_row,
                                                    gint new_col,
-                                                   XfdesktopFileIconManager *fmanager);
-static void xfdesktop_file_icon_manager_icon_activated(XfdesktopIconView *icon_view,
-                                                       XfdesktopFileIconManager *fmanager);
+                                                   MonitorData *mdata);
+static void xfdesktop_file_icon_manager_activate_selected(GtkWidget *widget,
+                                                          XfdesktopFileIconManager *fmanager);
 
 static GList *xfdesktop_file_icon_manager_get_selected_icons(XfdesktopFileIconManager *fmanager);
 
@@ -224,14 +237,14 @@ static void xfdesktop_file_icon_manager_icon_view_unrealized(GtkWidget *icon_vie
 static void xfdesktop_file_icon_manager_start_grid_resize(XfdesktopIconView *icon_view,
                                                           gint new_rows,
                                                           gint new_cols,
-                                                          XfdesktopFileIconManager *fmanager);
+                                                          MonitorData *mdata);
 static void xfdesktop_file_icon_manager_end_grid_resize(XfdesktopIconView *icon_view,
-                                                        XfdesktopFileIconManager *fmanager);
+                                                        MonitorData *mdata);
 
-static gboolean xfdesktop_file_icon_manager_get_cached_icon_position(XfdesktopFileIconManager *fmanager,
-                                                                     XfdesktopFileIcon *icon,
-                                                                     gint16 *row,
-                                                                     gint16 *col);
+static XfwMonitor *xfdesktop_file_icon_manager_get_cached_icon_position(XfdesktopFileIconManager *fmanager,
+                                                                        XfdesktopFileIcon *icon,
+                                                                        gint16 *row,
+                                                                        gint16 *col);
 
 static void model_ready(XfdesktopFileIconModel *fmodel,
                         XfdesktopFileIconManager *fmanager);
@@ -338,6 +351,10 @@ xfdesktop_file_icon_manager_class_init(XfdesktopFileIconManagerClass *klass)
 static void
 xfdesktop_file_icon_manager_init(XfdesktopFileIconManager *fmanager)
 {
+    fmanager->monitor_data = g_hash_table_new_full(g_direct_hash,
+                                                   g_direct_equal,
+                                                   g_object_unref,
+                                                   (GDestroyNotify)monitor_data_free);
     fmanager->ready = FALSE;
     fmanager->show_delete_menu = TRUE;
     fmanager->max_templates = 16;
@@ -392,15 +409,26 @@ xfdesktop_file_icon_manager_constructed(GObject *obj)
                                                                                  desktop_info));
     g_object_unref(desktop_info);
 
-    GList *desktops = xfdesktop_icon_view_manager_get_desktops(XFDESKTOP_ICON_VIEW_MANAGER(fmanager));
-    for (GList *l = desktops; l != NULL; l = l->next) {
-        XfceDesktop *desktop = XFCE_DESKTOP(l->data);
-        if (xfw_monitor_is_primary(xfce_desktop_get_monitor(desktop))) {
-            create_icon_view(fmanager, desktop);
-            break;
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+    gint screen_num = gdk_screen_get_number(fmanager->gscreen);
+G_GNUC_END_IGNORE_DEPRECATIONS
+    gchar *positions_file_relpath = g_strdup_printf("xfce4/desktop/icons.screen%d.yaml", screen_num);
+    gchar *positions_file_path = xfce_resource_save_location(XFCE_RESOURCE_CONFIG, positions_file_relpath, TRUE);
+    GFile *positions_file = g_file_new_for_path(positions_file_path);
+    fmanager->position_configs = xfdesktop_icon_position_configs_new(positions_file);
+
+    GError *error = NULL;
+    if (!xfdesktop_icon_position_configs_load(fmanager->position_configs, &error)) {
+        if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
+            g_message("Unable to load icon positions: %s", error->message);
         }
+        g_error_free(error);
     }
 
+    g_free(positions_file_relpath);
+    g_free(positions_file_path);
+    g_object_unref(positions_file);
+
     fmanager->model = xfdesktop_file_icon_model_new(channel, fmanager->folder, fmanager->gscreen);
     g_signal_connect(fmanager->model, "ready",
                      G_CALLBACK(model_ready), fmanager);
@@ -409,7 +437,11 @@ xfdesktop_file_icon_manager_constructed(GObject *obj)
     g_signal_connect_swapped(fmanager->model, "icon-position-request",
                              G_CALLBACK(xfdesktop_file_icon_manager_get_cached_icon_position), fmanager);
 
-    fmanager->filter = xfdesktop_file_icon_model_filter_new(channel, fmanager->model);
+    GList *desktops = xfdesktop_icon_view_manager_get_desktops(XFDESKTOP_ICON_VIEW_MANAGER(fmanager));
+    for (GList *l = desktops; l != NULL; l = l->next) {
+        XfceDesktop *desktop = XFCE_DESKTOP(l->data);
+        xfdesktop_file_icon_manager_desktop_added(XFDESKTOP_ICON_VIEW_MANAGER(fmanager), desktop);
+    }
 
     for (gsize i = 0; i < G_N_ELEMENTS(setting_bindings); ++i) {
         xfconf_g_property_bind(channel,
@@ -493,15 +525,7 @@ xfdesktop_file_icon_manager_dispose(GObject *obj)
 {
     XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(obj);
 
-    if(fmanager->save_icons_id) {
-        g_source_remove(fmanager->save_icons_id);
-        fmanager->save_icons_id = 0;
-        xfdesktop_file_icon_manager_save_icons(fmanager);
-    }
-
-    g_clear_object(&fmanager->holder);
-
-    g_clear_object(&fmanager->filter);
+    g_clear_pointer(&fmanager->monitor_data, g_hash_table_destroy);
     g_clear_object(&fmanager->model);
 
     G_OBJECT_CLASS(xfdesktop_file_icon_manager_parent_class)->dispose(obj);
@@ -512,6 +536,8 @@ xfdesktop_file_icon_manager_finalize(GObject *obj)
 {
     XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(obj);
 
+    xfdesktop_icon_position_configs_free(fmanager->position_configs);
+
     g_signal_handlers_disconnect_by_func(G_OBJECT(clipboard_manager),
                                          G_CALLBACK(xfdesktop_file_icon_manager_clipboard_changed),
                                          fmanager);
@@ -547,6 +573,30 @@ xfdesktop_file_icon_manager_icon_view_unrealized(GtkWidget *icon_view, Xfdesktop
     g_signal_handlers_disconnect_by_data(window_widget, fmanager);
 }
 
+static GtkWindow *
+toplevel_window_for_widget(GtkWidget *widget) {
+    if (GTK_IS_MENU_ITEM(widget)) {
+        GtkWidget *cur = widget;
+        while (cur != NULL) {
+            cur = gtk_widget_get_parent(cur);
+            if (GTK_IS_MENU(cur)) {
+                GtkWidget *attach_widget = gtk_menu_get_attach_widget(GTK_MENU(cur));
+                if (GTK_IS_MENU_ITEM(attach_widget)) {
+                    cur = attach_widget;
+                } else if (XFCE_IS_DESKTOP(attach_widget)) {
+                    return GTK_WINDOW(attach_widget);
+                } else if (XFDESKTOP_IS_ICON_VIEW(attach_widget)) {
+                    return GTK_WINDOW(gtk_widget_get_toplevel(attach_widget));
+                }
+            }
+        }
+    } else {
+        return GTK_WINDOW(gtk_widget_get_toplevel(widget));
+    }
+
+    return NULL;
+}
+
 /* icon signal handlers */
 
 static void
@@ -554,7 +604,7 @@ xfdesktop_file_icon_menu_executed(GtkWidget *widget, XfdesktopFileIconManager *f
     GList *selected = xfdesktop_file_icon_manager_get_selected_icons(fmanager);
     if (selected != NULL && selected->next == NULL) {
         XfdesktopIcon *icon = XFDESKTOP_ICON(selected->data);
-        xfdesktop_icon_activate(icon, GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(fmanager->holder))));
+        xfdesktop_icon_activate(icon, toplevel_window_for_widget(widget));
     }
 
     g_list_free(selected);
@@ -562,7 +612,7 @@ xfdesktop_file_icon_menu_executed(GtkWidget *widget, XfdesktopFileIconManager *f
 
 static void
 xfdesktop_file_icon_menu_open_all(GtkWidget *widget, XfdesktopFileIconManager *fmanager) {
-    xfdesktop_file_icon_manager_icon_activated(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder), fmanager);
+    xfdesktop_file_icon_manager_activate_selected(widget, fmanager);
 }
 
 static void
@@ -577,18 +627,18 @@ xfdesktop_file_icon_menu_rename(GtkWidget *widget, XfdesktopFileIconManager *fma
             files = g_list_append(files, xfdesktop_file_icon_peek_file(icon));
     }
 
-    GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
+    GtkWindow *toplevel = toplevel_window_for_widget(widget);
     if(g_list_length(files) == 1) {
         /* rename dialog for a single icon */
-        xfdesktop_file_utils_rename_file(g_list_first(files)->data, fmanager->gscreen, GTK_WINDOW(toplevel));
+        xfdesktop_file_utils_rename_file(g_list_first(files)->data, fmanager->gscreen, toplevel);
     } else if(g_list_length(files) > 1) {
         /* Bulk rename for multiple icons selected */
         GFile *desktop = xfdesktop_file_icon_peek_file(fmanager->desktop_icon);
 
-        xfdesktop_file_utils_bulk_rename(desktop, files, fmanager->gscreen, GTK_WINDOW(toplevel));
+        xfdesktop_file_utils_bulk_rename(desktop, files, fmanager->gscreen, toplevel);
     } else {
         /* Nothing valid to rename */
-        xfce_message_dialog(GTK_WINDOW(toplevel),
+        xfce_message_dialog(toplevel,
                             _("Rename Error"), "dialog-error",
                             _("The files could not be renamed"),
                             _("None of the icons selected support being renamed."),
@@ -601,36 +651,32 @@ xfdesktop_file_icon_menu_rename(GtkWidget *widget, XfdesktopFileIconManager *fma
 }
 
 static void
-xfdesktop_file_icon_manager_delete_files(XfdesktopFileIconManager *fmanager, GList *files) {
+xfdesktop_file_icon_manager_delete_files(XfdesktopFileIconManager *fmanager, GtkWidget *widget, GList *files) {
     GList *gfiles = NULL;
     for (GList *lp = g_list_last(files); lp != NULL; lp = lp->prev) {
         gfiles = g_list_prepend(gfiles, xfdesktop_file_icon_peek_file(lp->data));
     }
 
-    GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
-    xfdesktop_file_utils_unlink_files(gfiles, fmanager->gscreen, GTK_WINDOW(toplevel));
+    xfdesktop_file_utils_unlink_files(gfiles, fmanager->gscreen, toplevel_window_for_widget(widget));
 
     g_list_free(gfiles);
 }
 
 static gboolean
-xfdesktop_file_icon_manager_trash_files(XfdesktopFileIconManager *fmanager,
-                                        GList *files)
-{
+xfdesktop_file_icon_manager_trash_files(XfdesktopFileIconManager *fmanager, GtkWidget *widget, GList *files) {
     GList *gfiles = NULL;
     for (GList *lp = g_list_last(files); lp != NULL; lp = lp->prev) {
         gfiles = g_list_prepend(gfiles, xfdesktop_file_icon_peek_file(lp->data));
     }
 
-    GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
-    xfdesktop_file_utils_trash_files(gfiles, fmanager->gscreen, GTK_WINDOW(toplevel));
+    xfdesktop_file_utils_trash_files(gfiles, fmanager->gscreen, toplevel_window_for_widget(widget));
 
     g_list_free(gfiles);
     return TRUE;
 }
 
 static void
-xfdesktop_file_icon_manager_delete_selected(XfdesktopFileIconManager *fmanager, gboolean force_delete) {
+xfdesktop_file_icon_manager_delete_selected(XfdesktopFileIconManager *fmanager, GtkWidget *widget, gboolean force_delete) {
     GList *selected = xfdesktop_file_icon_manager_get_selected_icons(fmanager);
     if(!selected)
         return;
@@ -663,9 +709,9 @@ xfdesktop_file_icon_manager_delete_selected(XfdesktopFileIconManager *fmanager,
     g_list_foreach(selected, xfdesktop_object_ref, NULL);
 
     if(!force_delete) {
-        xfdesktop_file_icon_manager_trash_files(fmanager, selected);
+        xfdesktop_file_icon_manager_trash_files(fmanager, widget, selected);
     } else {
-        xfdesktop_file_icon_manager_delete_files(fmanager, selected);
+        xfdesktop_file_icon_manager_delete_files(fmanager, widget, selected);
     }
 
     g_list_free_full(selected, g_object_unref);
@@ -683,19 +729,18 @@ xfdesktop_file_icon_menu_app_info_executed(GtkWidget *widget, XfdesktopFileIconM
     GAppInfo *app_info = g_object_get_qdata(G_OBJECT(widget), xfdesktop_app_info_quark);
     if (app_info != NULL) {
         /* prepare the launch context and configure its screen */
-        GtkWidget *icon_view = GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder));
-        GdkAppLaunchContext *context = gdk_display_get_app_launch_context(gtk_widget_get_display(icon_view));
-        GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
-        gdk_app_launch_context_set_screen(context, gtk_widget_get_screen(toplevel));
+        GdkAppLaunchContext *context = gdk_display_get_app_launch_context(gtk_widget_get_display(widget));
+        gdk_app_launch_context_set_screen(context, gtk_widget_get_screen(widget));
 
         /* try to launch the application */
         GError *error = NULL;
         if (!xfdesktop_file_utils_app_info_launch(app_info, fmanager->folder, selected,
                                                   G_APP_LAUNCH_CONTEXT(context), &error))
         {
+            GtkWindow *toplevel = toplevel_window_for_widget(widget);
             gchar *primary = g_markup_printf_escaped(_("Unable to launch \"%s\":"),
                                                      g_app_info_get_name(app_info));
-            xfce_message_dialog(GTK_WINDOW(toplevel), _("Launch Error"),
+            xfce_message_dialog(toplevel, _("Launch Error"),
                                 "dialog-error", primary, error->message,
                                 XFCE_BUTTON_TYPE_MIXED, "window-close", _("_Close"), GTK_RESPONSE_ACCEPT,
                                 NULL);
@@ -716,8 +761,7 @@ xfdesktop_file_icon_menu_open_folder(GtkWidget *widget, XfdesktopFileIconManager
     }
 
     if (selected != NULL) {
-        GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
-        xfdesktop_file_utils_open_folders(selected, fmanager->gscreen, GTK_WINDOW(toplevel));
+        xfdesktop_file_utils_open_folders(selected, fmanager->gscreen, toplevel_window_for_widget(widget));
         g_list_free(selected);
     }
 }
@@ -731,8 +775,7 @@ xfdesktop_file_icon_menu_open_desktop(GtkWidget *widget, XfdesktopFileIconManage
     };
 
     if (link.data != NULL) {
-        GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
-        xfdesktop_file_utils_open_folders(&link, fmanager->gscreen, GTK_WINDOW(toplevel));
+        xfdesktop_file_utils_open_folders(&link, fmanager->gscreen, toplevel_window_for_widget(widget));
     }
 }
 
@@ -741,9 +784,9 @@ xfdesktop_file_icon_menu_other_app(GtkWidget *widget, XfdesktopFileIconManager *
     GList *selected = xfdesktop_file_icon_manager_get_selected_icons(fmanager);
     if (selected != NULL && selected->next == NULL) {
         XfdesktopFileIcon *icon = XFDESKTOP_FILE_ICON(selected->data);
-        GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
         GFile *file = xfdesktop_file_icon_peek_file(icon);
-        xfdesktop_file_utils_display_app_chooser_dialog(file, TRUE, FALSE, fmanager->gscreen, GTK_WINDOW(toplevel));
+        GtkWindow *toplevel = toplevel_window_for_widget(widget);
+        xfdesktop_file_utils_display_app_chooser_dialog(file, TRUE, FALSE, fmanager->gscreen, toplevel);
     }
 
     g_list_free(selected);
@@ -754,9 +797,9 @@ xfdesktop_file_icon_menu_set_default_app(GtkWidget *widget, XfdesktopFileIconMan
     GList *selected = xfdesktop_file_icon_manager_get_selected_icons(fmanager);
     if (selected != NULL && selected->next == NULL) {
         XfdesktopFileIcon *icon = XFDESKTOP_FILE_ICON(selected->data);
-        GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
         GFile *file = xfdesktop_file_icon_peek_file(icon);
-        xfdesktop_file_utils_display_app_chooser_dialog(file, TRUE, TRUE, fmanager->gscreen, GTK_WINDOW(toplevel));
+        GtkWindow *toplevel = toplevel_window_for_widget(widget);
+        xfdesktop_file_utils_display_app_chooser_dialog(file, TRUE, TRUE, fmanager->gscreen, toplevel);
     }
 
     g_list_free(selected);
@@ -782,12 +825,12 @@ xfdesktop_file_icon_menu_copy(GtkWidget *widget, XfdesktopFileIconManager *fmana
 
 static void
 xfdesktop_file_icon_menu_trash(GtkWidget *widget, XfdesktopFileIconManager *fmanager) {
-    xfdesktop_file_icon_manager_delete_selected(fmanager, FALSE);
+    xfdesktop_file_icon_manager_delete_selected(fmanager, widget, FALSE);
 }
 
 static void
 xfdesktop_file_icon_menu_delete(GtkWidget *widget, XfdesktopFileIconManager *fmanager) {
-    xfdesktop_file_icon_manager_delete_selected(fmanager, TRUE);
+    xfdesktop_file_icon_manager_delete_selected(fmanager, widget, TRUE);
 }
 
 static void
@@ -820,14 +863,22 @@ xfdesktop_file_icon_menu_arrange_icons(GtkWidget *widget, XfdesktopFileIconManag
                             "%s",
                             _("This will reorder all desktop items and place them on different screen positions.\nAre you sure?")))
     {
-        xfdesktop_icon_view_sort_icons(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder), GTK_SORT_ASCENDING);
+        xfdesktop_file_icon_manager_sort_icons(XFDESKTOP_ICON_VIEW_MANAGER(fmanager), GTK_SORT_ASCENDING);
     }
 }
 
 static void
 xfdesktop_file_icon_menu_next_background(GtkWidget *widget, XfdesktopFileIconManager *fmanager) {
-    XfceDesktop *desktop = fmanager->holder != NULL ? xfdesktop_icon_view_holder_get_desktop(fmanager->holder) : NULL;
-    xfce_desktop_refresh(desktop, TRUE);
+    // FIXME: need to handle spanning in a special way?
+
+    GHashTableIter iter;
+    g_hash_table_iter_init(&iter, fmanager->monitor_data);
+
+    MonitorData *mdata;
+    while (g_hash_table_iter_next(&iter, NULL, (gpointer)&mdata)) {
+        XfceDesktop *desktop = xfdesktop_icon_view_holder_get_desktop(mdata->holder);
+        xfce_desktop_refresh(desktop, TRUE);
+    }
 }
 
 static void
@@ -839,22 +890,20 @@ xfdesktop_file_icon_menu_properties(GtkWidget *widget, XfdesktopFileIconManager
     }
 
     if (selected != NULL) {
-        GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
-        xfdesktop_file_utils_show_properties_dialog(selected, fmanager->gscreen, GTK_WINDOW(toplevel));
+        xfdesktop_file_utils_show_properties_dialog(selected, fmanager->gscreen, toplevel_window_for_widget(widget));
         g_list_free(selected);
     }
 }
 
 static void
 xfdesktop_file_icon_manager_desktop_properties(GtkWidget *widget, XfdesktopFileIconManager *fmanager) {
-    GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
     GFile *file = xfdesktop_file_icon_peek_file (fmanager->desktop_icon);
     GList file_l = {
         .data = file,
         .next = NULL,
     };
 
-    xfdesktop_file_utils_show_properties_dialog(&file_l, fmanager->gscreen, GTK_WINDOW(parent));
+    xfdesktop_file_utils_show_properties_dialog(&file_l, fmanager->gscreen, toplevel_window_for_widget(widget));
 }
 
 static GtkWidget *
@@ -931,8 +980,8 @@ xfdesktop_file_icon_menu_create_launcher(GtkWidget *widget, XfdesktopFileIconMan
 
     GError *error = NULL;
     if (!xfce_spawn_command_line(fmanager->gscreen, cmd, FALSE, FALSE, TRUE, &error)) {
-        GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
-        xfce_message_dialog(GTK_WINDOW(toplevel), _("Launch Error"),
+        xfce_message_dialog(toplevel_window_for_widget(widget),
+                            _("Launch Error"),
                             "dialog-error",
                             _("Unable to launch \"exo-desktop-item-edit\", which is required to create and edit launchers and links on the desktop."),
                             error->message,
@@ -949,25 +998,24 @@ xfdesktop_file_icon_menu_create_launcher(GtkWidget *widget, XfdesktopFileIconMan
 
 static void
 xfdesktop_file_icon_menu_create_folder(GtkWidget *widget, XfdesktopFileIconManager *fmanager) {
-    GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
-    xfdesktop_file_utils_create_file(fmanager->folder, "inode/directory",
+    xfdesktop_file_utils_create_file(fmanager->folder,
+                                     "inode/directory",
                                      fmanager->gscreen,
-                                     GTK_WINDOW(toplevel));
+                                     toplevel_window_for_widget(widget));
 }
 
 static void
 xfdesktop_file_icon_template_item_activated(GtkWidget *mi, XfdesktopFileIconManager *fmanager) {
     GFile *file = g_object_get_data(G_OBJECT(mi), "file");
-    GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
 
     if(file) {
         xfdesktop_file_utils_create_file_from_template(fmanager->folder, file,
                                                        fmanager->gscreen,
-                                                        GTK_WINDOW(toplevel));
+                                                       toplevel_window_for_widget(mi));
     } else {
         xfdesktop_file_utils_create_file(fmanager->folder, "text/plain",
                                          fmanager->gscreen,
-                                         GTK_WINDOW(toplevel));
+                                         toplevel_window_for_widget(mi));
     }
 }
 
@@ -1151,10 +1199,10 @@ xfdesktop_settings_launch(GtkWidget *w, XfdesktopFileIconManager *fmanager) {
 
     GError *error = NULL;
     if (!xfce_spawn_command_line(fmanager->gscreen, cmd, FALSE, TRUE, TRUE, &error)) {
-        GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
         /* printf is to be translator-friendly */
         gchar *primary = g_strdup_printf(_("Unable to launch \"%s\":"), cmd);
-        xfce_message_dialog(GTK_WINDOW(toplevel), _("Launch Error"),
+        xfce_message_dialog(toplevel_window_for_widget(w),
+                            _("Launch Error"),
                             "dialog-error", primary, error->message,
                             XFCE_BUTTON_TYPE_MIXED, "window-close", _("_Close"), GTK_RESPONSE_ACCEPT,
                             NULL);
@@ -1167,6 +1215,9 @@ xfdesktop_settings_launch(GtkWidget *w, XfdesktopFileIconManager *fmanager) {
 
 static void
 create_icon_view(XfdesktopFileIconManager *fmanager, XfceDesktop *desktop) {
+    MonitorData *mdata = g_new0(MonitorData, 1);
+    mdata->fmanager = fmanager;
+
     XfwScreen *screen = xfdesktop_icon_view_manager_get_screen(XFDESKTOP_ICON_VIEW_MANAGER(fmanager));
     XfconfChannel *channel = xfdesktop_icon_view_manager_get_channel(XFDESKTOP_ICON_VIEW_MANAGER(fmanager));
     XfdesktopIconView *icon_view = g_object_new(XFDESKTOP_TYPE_ICON_VIEW,
@@ -1192,76 +1243,185 @@ create_icon_view(XfdesktopFileIconManager *fmanager, XfceDesktop *desktop) {
                                          GDK_ACTION_LINK | GDK_ACTION_COPY | GDK_ACTION_MOVE);
 
     g_signal_connect(icon_view, "icon-moved",
-                     G_CALLBACK(xfdesktop_file_icon_manager_icon_moved), fmanager);
+                     G_CALLBACK(xfdesktop_file_icon_manager_icon_moved), mdata);
     g_signal_connect(icon_view, "icon-activated",
-                     G_CALLBACK(xfdesktop_file_icon_manager_icon_activated), fmanager);
+                     G_CALLBACK(xfdesktop_file_icon_manager_activate_selected), fmanager);
     g_signal_connect(icon_view, "realize",
                      G_CALLBACK(xfdesktop_file_icon_manager_icon_view_realized), fmanager);
     g_signal_connect(icon_view, "unrealize",
                      G_CALLBACK(xfdesktop_file_icon_manager_icon_view_unrealized), fmanager);
     // DnD signals
     g_signal_connect(icon_view, "drag-actions-get",
-                     G_CALLBACK(xfdesktop_file_icon_manager_drag_actions_get), fmanager);
+                     G_CALLBACK(xfdesktop_file_icon_manager_drag_actions_get), mdata);
     g_signal_connect(icon_view, "drop-actions-get",
-                     G_CALLBACK(xfdesktop_file_icon_manager_drop_actions_get), fmanager);
+                     G_CALLBACK(xfdesktop_file_icon_manager_drop_actions_get), mdata);
     g_signal_connect(icon_view, "drag-drop-ask",
                      G_CALLBACK(xfdesktop_file_icon_manager_drag_drop_ask), fmanager);
     g_signal_connect(icon_view, "drag-drop-item",
-                     G_CALLBACK(xfdesktop_file_icon_manager_drag_drop_item), fmanager);
+                     G_CALLBACK(xfdesktop_file_icon_manager_drag_drop_item), mdata);
     g_signal_connect(icon_view, "drag-drop-items",
-                     G_CALLBACK(xfdesktop_file_icon_manager_drag_drop_items), fmanager);
+                     G_CALLBACK(xfdesktop_file_icon_manager_drag_drop_items), mdata);
     g_signal_connect(icon_view, "drag-data-get",
-                     G_CALLBACK(xfdesktop_file_icon_manager_drag_data_get), fmanager);
+                     G_CALLBACK(xfdesktop_file_icon_manager_drag_data_get), mdata);
     g_signal_connect(icon_view, "drag-item-data-received",
-                     G_CALLBACK(xfdesktop_file_icon_manager_drag_item_data_received), fmanager);
+                     G_CALLBACK(xfdesktop_file_icon_manager_drag_item_data_received), mdata);
     g_signal_connect(icon_view, "drop-propose-action",
-                     G_CALLBACK(xfdesktop_file_icon_manager_drop_propose_action), fmanager);
+                     G_CALLBACK(xfdesktop_file_icon_manager_drop_propose_action), mdata);
     // Below signals allow us to sort icons and replace them where they belong in the newly-sized view
     g_signal_connect(G_OBJECT(icon_view), "start-grid-resize",
-                     G_CALLBACK(xfdesktop_file_icon_manager_start_grid_resize), fmanager);
+                     G_CALLBACK(xfdesktop_file_icon_manager_start_grid_resize), mdata);
     g_signal_connect(G_OBJECT(icon_view), "end-grid-resize",
-                     G_CALLBACK(xfdesktop_file_icon_manager_end_grid_resize), fmanager);
+                     G_CALLBACK(xfdesktop_file_icon_manager_end_grid_resize), mdata);
 
     if (gtk_widget_get_realized(GTK_WIDGET(icon_view))) {
         xfdesktop_file_icon_manager_icon_view_realized(GTK_WIDGET(icon_view), fmanager);
     }
 
-    fmanager->holder = xfdesktop_icon_view_holder_new(screen, desktop, icon_view);
+    mdata->holder = xfdesktop_icon_view_holder_new(screen, desktop, icon_view);
+
+    XfwMonitor *monitor = xfce_desktop_get_monitor(desktop);
+    XfdesktopIconPositionLevel level;
+    if (xfw_monitor_is_primary(monitor)) {
+        level = XFDESKTOP_ICON_POSITION_LEVEL_PRIMARY;
+    } else if (g_list_length(xfw_screen_get_monitors(screen)) == 2
+               || g_list_nth_data(xfw_screen_get_monitors(screen), 0) == monitor
+               || g_list_nth_data(xfw_screen_get_monitors(screen), 1) == monitor)
+    {
+        level = XFDESKTOP_ICON_POSITION_LEVEL_SECONDARY;
+    } else {
+        level = XFDESKTOP_ICON_POSITION_LEVEL_OTHER;
+    }
+    GList *candidates = NULL;
+    mdata->position_config = xfdesktop_icon_position_configs_add_monitor(fmanager->position_configs,
+                                                                         monitor,
+                                                                         level,
+                                                                         &candidates);
+
+    if (mdata->position_config == NULL) {
+        g_assert(candidates != NULL);
+
+        GtkBuilder *builder = gtk_builder_new_from_resource("/org/xfce/xfdesktop/monitor-candidates-chooser.glade");
+        g_assert(builder != NULL);
+
+        GtkWidget *dialog = GTK_WIDGET(gtk_builder_get_object(builder, "monitor_candidates_chooser"));
+
+        gchar *monitor_question_text = g_strdup_printf( _("Would you like to assign an existing desktop icon layout to monitor <b>%s</b>?"),
+                                                       xfw_monitor_get_description(monitor));
+        GtkWidget *monitor_question_label = GTK_WIDGET(gtk_builder_get_object(builder, "monitor_question_label"));
+        gtk_label_set_text(GTK_LABEL(monitor_question_label), monitor_question_text);
+        g_free(monitor_question_text);
+
+        GtkWidget *monitor_list_view = GTK_WIDGET(gtk_builder_get_object(builder, "monitor_list_view"));
+        GtkCellRenderer *name_renderer = gtk_cell_renderer_text_new();
+        GtkTreeViewColumn *col = gtk_tree_view_column_new_with_attributes(N_("Monitors"),
+                                                                          name_renderer,
+                                                                          "text", 0,
+                                                                          NULL);
+        gtk_tree_view_append_column(GTK_TREE_VIEW(monitor_list_view), col);
+
+        GtkListStore *monitor_list = GTK_LIST_STORE(gtk_builder_get_object(builder, "monitor_list"));
+        for (GList *lc = candidates; lc != NULL; lc = lc->next) {
+            XfdesktopIconPositionConfig *candidate = lc->data;
+
+            GList *names = xfdesktop_icon_position_config_get_monitor_display_names(candidate);
+            for (GList *ln = names; ln != NULL; ln = ln->next) {
+                const gchar *name = ln->data;
+                GtkTreeIter iter;
+                gtk_list_store_append(monitor_list, &iter);
+                gtk_list_store_set(monitor_list, &iter,
+                                   0, name,
+                                   1, candidate,
+                                   -1);
+            }
+            g_list_free(names);
+        }
+
+        GtkWidget *radio_auto_assign = GTK_WIDGET(gtk_builder_get_object(builder, "radio_auto_assign"));
+        GtkWidget *chk_always_auto_assign = GTK_WIDGET(gtk_builder_get_object(builder, "chk_always_auto_assign"));
+        g_object_bind_property(radio_auto_assign, "active", chk_always_auto_assign, "sensitive", G_BINDING_SYNC_CREATE);
+        GtkWidget *radio_select_monitor = GTK_WIDGET(gtk_builder_get_object(builder, "radio_select_monitor"));
+
+        gtk_widget_show_all(dialog);
+        GtkResponseType response = gtk_dialog_run(GTK_DIALOG(dialog));
+        if (response == GTK_RESPONSE_ACCEPT) {
+            if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio_select_monitor))) {
+                GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(monitor_list_view));
+                GtkTreeIter iter;
+                if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
+                    gtk_tree_model_get(GTK_TREE_MODEL(monitor_list), &iter, 1, &mdata->position_config, -1);
+                }
+            }
+        }
+
+        if (mdata->position_config == NULL) {
+            // Either they selected auto-assign, didn't select anything, or
+            // canceled the dialog, so we auto-assign for them.
+            mdata->position_config = candidates->data;
+        }
+
+        xfdesktop_icon_position_configs_assign_monitor(fmanager->position_configs, mdata->position_config, monitor);
+
+        g_list_free(candidates);
+        g_object_unref(builder);
+    }
+
+    mdata->filter = xfdesktop_file_icon_model_filter_new(channel, fmanager->position_configs, monitor, fmanager->model);
+    if (fmanager->ready) {
+        xfdesktop_icon_view_set_model(icon_view, GTK_TREE_MODEL(mdata->filter));
+    }
+
+    g_hash_table_insert(fmanager->monitor_data, g_object_ref(monitor), mdata);
+}
+
+static void
+update_icon_monitors(XfdesktopFileIconManager *fmanager) {
+    GtkTreeIter iter;
+    if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(fmanager->model), &iter)) {
+        do {
+            XfdesktopFileIcon *icon = xfdesktop_file_icon_model_get_icon(fmanager->model, &iter);
+            if (icon != NULL) {
+                gboolean changed = FALSE;
+
+                gchar *identifier = xfdesktop_icon_get_identifier(XFDESKTOP_ICON(icon));
+                XfwMonitor *icon_monitor = NULL;
+                gint row, col;
+                if (xfdesktop_icon_position_configs_lookup(fmanager->position_configs, identifier, &icon_monitor, &row, &col)) {
+                    changed |= xfdesktop_icon_set_monitor(XFDESKTOP_ICON(icon), icon_monitor);
+                    changed |= xfdesktop_icon_set_position(XFDESKTOP_ICON(icon), row, col);
+                } else {
+                    XfwScreen *screen = xfdesktop_icon_view_manager_get_screen(XFDESKTOP_ICON_VIEW_MANAGER(fmanager));
+                    XfwMonitor *primary = xfw_screen_get_primary_monitor(screen);
+                    changed |= xfdesktop_icon_set_monitor(XFDESKTOP_ICON(icon), primary);
+                }
+
+                if (changed) {
+                    GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(fmanager->model), &iter);
+                    gtk_tree_model_row_changed(GTK_TREE_MODEL(fmanager->model), path, &iter);
+                    gtk_tree_path_free(path);
+                }
+                g_free(identifier);
+            }
+        } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(fmanager->model), &iter));
+    }
 }
 
 static void
 xfdesktop_file_icon_manager_desktop_added(XfdesktopIconViewManager *manager, XfceDesktop *desktop) {
     TRACE("entering");
-    if (xfw_monitor_is_primary(xfce_desktop_get_monitor(desktop))) {
-        XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(manager);
-        if (fmanager->holder == NULL || xfdesktop_icon_view_holder_get_desktop(fmanager->holder) != desktop) {
-            DBG("creating new icon view");
-            g_clear_object(&fmanager->holder);
-            create_icon_view(fmanager, desktop);
-            if (fmanager->ready) {
-                XfdesktopIconView *icon_view = xfdesktop_icon_view_holder_get_icon_view(fmanager->holder);
-                xfdesktop_icon_view_set_model(icon_view, GTK_TREE_MODEL(fmanager->filter));
-            } else {
-                xfdesktop_file_icon_model_reload(fmanager->model);
-            }
-        }
 
-    }
+    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(manager);
+    create_icon_view(fmanager, desktop);
+    update_icon_monitors(fmanager);
 }
 
 static void
 xfdesktop_file_icon_manager_desktop_removed(XfdesktopIconViewManager *manager, XfceDesktop *desktop) {
     TRACE("entering");
     XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(manager);
-    if (fmanager->holder != NULL && desktop == xfdesktop_icon_view_holder_get_desktop(fmanager->holder)) {
-        DBG("dropping old icon view");
-        g_clear_object(&fmanager->holder);
-
-        GList *desktops = xfdesktop_icon_view_manager_get_desktops(manager);
-        for (GList *l = desktops; l != NULL; l = l->next) {
-            xfdesktop_file_icon_manager_desktop_added(manager, XFCE_DESKTOP(l->data));
-        }
-    }
+    XfwMonitor *monitor = xfce_desktop_get_monitor(desktop);
+    xfdesktop_icon_position_configs_unassign_monitor(fmanager->position_configs, monitor);
+    update_icon_monitors(fmanager);
+    g_hash_table_remove(fmanager->monitor_data, monitor);
 }
 
 static GtkWidget *
@@ -1305,10 +1465,7 @@ xfdesktop_file_icon_manager_get_context_menu(XfdesktopIconViewManager *manager,
     GtkWidget *menu = gtk_menu_new();
     gtk_menu_set_reserve_toggle_size(GTK_MENU(menu), FALSE);
 
-    GList *selected = NULL;
-    if (XFCE_DESKTOP(widget) == xfdesktop_icon_view_holder_get_desktop(fmanager->holder)) {
-        selected = xfdesktop_file_icon_manager_get_selected_icons(fmanager);
-    }
+    GList *selected = xfdesktop_file_icon_manager_get_selected_icons(fmanager);
     if(!selected) {
         /* assume click on the desktop itself */
         selected = g_list_append(selected, fmanager->desktop_icon);
@@ -1698,28 +1855,28 @@ xfdesktop_file_icon_manager_get_context_menu(XfdesktopIconViewManager *manager,
             for(GList *l = fmanager->thunarx_menu_providers; l; l = l->next) {
                 ThunarxMenuProvider *provider = THUNARX_MENU_PROVIDER(l->data);
 
-                GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
+                GtkWidget *toplevel = GTK_WIDGET(toplevel_window_for_widget(widget));
                 GList *menu_items = NULL;
                 if(selected->data == fmanager->desktop_icon) {
                     /* click on the desktop itself, only show folder actions */
                     menu_items = thunarx_menu_provider_get_folder_menu_items(provider,
-                                                                                toplevel,
-                                                                                THUNARX_FILE_INFO(file_icon));
+                                                                             toplevel,
+                                                                             THUNARX_FILE_INFO(file_icon));
                 }
                 else {
                     /* thunar file specific actions (allows them to operate on folders
                         * that are on the desktop as well) */
-                    menu_items = thunarx_menu_provider_get_file_menu_items(provider,
-                                                                            toplevel,
-                                                                            selected);       
+                    menu_items = thunarx_menu_provider_get_file_menu_items(provider, toplevel, selected);
                 }
 
                 for (GList *lp_item = menu_items; lp_item != NULL; lp_item = lp_item->next) {
-                    gtk_menu_item = xfdesktop_menu_create_menu_item_from_thunarx_menu_item(lp_item->data, GTK_MENU_SHELL (menu));
+                    gtk_menu_item = xfdesktop_menu_create_menu_item_from_thunarx_menu_item(lp_item->data,
+                                                                                           GTK_MENU_SHELL(menu));
 
                     /* Each thunarx_menu_item will be destroyed together with its related gtk_menu_item*/
-                    g_signal_connect_swapped(G_OBJECT(gtk_menu_item), "destroy", G_CALLBACK(g_object_unref), lp_item->data);
-                    }
+                    g_signal_connect_swapped(G_OBJECT(gtk_menu_item), "destroy",
+                                             G_CALLBACK(g_object_unref), lp_item->data);
+                }
 
                 g_list_free (menu_items);
             }
@@ -1745,7 +1902,8 @@ xfdesktop_file_icon_manager_get_context_menu(XfdesktopIconViewManager *manager,
                           G_CALLBACK(xfdesktop_file_icon_menu_arrange_icons),
                           fmanager);
 
-            XfceDesktop *desktop = xfdesktop_icon_view_holder_get_desktop(fmanager->holder);
+            g_assert(XFCE_IS_DESKTOP(widget));  // XXX
+            XfceDesktop *desktop = XFCE_DESKTOP(widget);
             XfwMonitor *monitor = xfce_desktop_get_monitor(desktop);
 
             XfwScreen *xfw_screen = xfdesktop_icon_view_manager_get_screen(XFDESKTOP_ICON_VIEW_MANAGER(fmanager));
@@ -1802,184 +1960,77 @@ xfdesktop_file_icon_manager_get_context_menu(XfdesktopIconViewManager *manager,
 static void
 xfdesktop_file_icon_manager_sort_icons(XfdesktopIconViewManager *manager, GtkSortType sort_type) {
     XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(manager);
-    xfdesktop_icon_view_sort_icons(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder), sort_type);
-}
+    // XXX: should we rearrange within each monitor, or rearrange all onto the primary?
 
-static void
-xfdesktop_file_icon_manager_get_icon_view_size(XfdesktopFileIconManager *fmanager, gint *width, gint *height) {
-    g_return_if_fail(width != NULL && height != NULL);
+    GHashTableIter iter;
+    g_hash_table_iter_init(&iter, fmanager->monitor_data);
 
-    gtk_widget_get_size_request(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)), width, height);
-    if (*width <= 0 || *height <= 0) {
-        GtkRequisition req;
-        gtk_widget_get_preferred_size(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)), &req, NULL);
-        *width = req.width;
-        *height = req.height;
+    MonitorData *mdata;
+    while (g_hash_table_iter_next(&iter, NULL, (gpointer)&mdata)) {
+        XfdesktopIconView *icon_view = xfdesktop_icon_view_holder_get_icon_view(mdata->holder);
+        xfdesktop_icon_view_sort_icons(icon_view, sort_type);
     }
 }
 
-static gboolean
-xfdesktop_file_icon_manager_save_icons_idled(gpointer user_data)
+static XfwMonitor *
+xfdesktop_file_icon_manager_get_cached_icon_position(XfdesktopFileIconManager *fmanager,
+                                                     XfdesktopFileIcon *icon,
+                                                     gint16 *ret_row,
+                                                     gint16 *ret_col)
 {
-    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
-    fmanager->save_icons_id = 0;
-
-    gint width = -1, height = -1;
-    xfdesktop_file_icon_manager_get_icon_view_size(fmanager, &width, &height);
-
-    gchar *relpath = g_strdup_printf("xfce4/desktop/icons.screen%d-%dx%d.rc", 0, width, height);
-    gchar *path = xfce_resource_save_location(XFCE_RESOURCE_CONFIG, relpath, TRUE);
-    g_free(relpath);
-
-    if(!path)
-        return FALSE;
-
-    XF_DEBUG("saving to: %s", path);
-
-    gchar *tmppath = g_strconcat(path, ".new", NULL);
-
-    XfceRc *rcfile = xfce_rc_simple_open(tmppath, FALSE);
-    if(!rcfile) {
-        g_warning("Unable to determine location of icon position cache file.  " \
-                  "Icon positions will not be saved.");
-        g_free(path);
-        g_free(tmppath);
-        return FALSE;
-    }
-
-    xfce_rc_set_group(rcfile, XFDESKTOP_RC_VERSION_STAMP);
-    xfce_rc_write_bool_entry(rcfile, "4.10.3+", TRUE);
-
-    GtkTreeIter iter;
-    if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(fmanager->filter), &iter)) {
-        do {
-            XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, &iter);
-            if (icon != NULL) {
-                gint16 row, col;
-
-                if (xfdesktop_icon_get_position(XFDESKTOP_ICON(icon), &row, &col)) {
-                    gchar *identifier = xfdesktop_icon_get_identifier(XFDESKTOP_ICON(icon));
-                    /* Attempt to use the identifier, fall back to using the labels. */
-                    if (identifier != NULL) {
-                        xfce_rc_set_group(rcfile, identifier);
-                        g_free(identifier);
-                    } else {
-                        xfce_rc_set_group(rcfile, xfdesktop_icon_peek_label(XFDESKTOP_ICON(icon)));
-                    }
-
-                    xfce_rc_write_int_entry(rcfile, "row", row);
-                    xfce_rc_write_int_entry(rcfile, "col", col);
-                }
-            }
-        } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(fmanager->filter), &iter));
-    }
-
-    xfce_rc_flush(rcfile);
-    xfce_rc_close(rcfile);
-
-    if(g_file_test(tmppath, G_FILE_TEST_EXISTS)) {
-        if(rename(tmppath, path)) {
-            g_warning("Unable to rename temp file to %s: %s", path,
-                      strerror(errno));
-            unlink(tmppath);
-        }
-        else {
-            gchar *last_path = xfce_resource_save_location(XFCE_RESOURCE_CONFIG, "xfce4/desktop/icons.screen.latest.rc", TRUE);
-            if(last_path != NULL) {
-                unlink(last_path);
-                if(symlink(path, last_path) != 0)
-                   g_warning("Unable to create symbolic link: %s",
-                             strerror(errno));
-                g_free(last_path);
-            }
-        }
+    g_return_val_if_fail(XFDESKTOP_IS_FILE_ICON_MANAGER(fmanager), NULL);
+    g_return_val_if_fail(ret_row != NULL && ret_col != NULL, NULL);
+
+    gchar *identifier = xfdesktop_icon_get_identifier(XFDESKTOP_ICON(icon));
+    XfwMonitor *monitor = NULL;
+    gint row = -1;
+    gint col = -1;
+    gboolean success = xfdesktop_icon_position_configs_lookup(fmanager->position_configs,
+                                                              identifier,
+                                                              &monitor,
+                                                              &row,
+                                                              &col);
+    g_free(identifier);
+    if (success) {
+        *ret_row = row;
+        *ret_col = col;
+        return monitor;
     } else {
-        XF_DEBUG("didn't write anything in the RC file, desktop is probably empty");
+        *ret_row = -1;
+        *ret_col = -1;
+        return xfw_screen_get_primary_monitor(xfdesktop_icon_view_manager_get_screen(XFDESKTOP_ICON_VIEW_MANAGER(fmanager)));
     }
-
-    g_free(path);
-    g_free(tmppath);
-
-    return FALSE;
 }
 
 static void
-xfdesktop_file_icon_manager_save_icons(XfdesktopFileIconManager *fmanager)
-{
-    if (fmanager->save_icons_id != 0) {
-        g_source_remove(fmanager->save_icons_id);
-    }
-
-    fmanager->save_icons_id = g_timeout_add(SAVE_DELAY,
-                                            xfdesktop_file_icon_manager_save_icons_idled,
-                                            fmanager);
-}
-
-static gboolean
-xfdesktop_file_icon_manager_get_cached_icon_position(XfdesktopFileIconManager *fmanager,
-                                                     XfdesktopFileIcon *icon,
-                                                     gint16 *row,
-                                                     gint16 *col)
-{
-    g_return_val_if_fail(XFDESKTOP_IS_FILE_ICON_MANAGER(fmanager) && fmanager != NULL, FALSE);
-    g_return_val_if_fail(row != NULL && col != NULL, FALSE);
-
-    gint width = -1, height = -1;
-    xfdesktop_file_icon_manager_get_icon_view_size(fmanager, &width, &height);
-
-    gchar *relpath = g_strdup_printf("xfce4/desktop/icons.screen%d-%dx%d.rc", 0, width, height);
-    gchar *filename = xfce_resource_lookup(XFCE_RESOURCE_CONFIG, relpath);
-    g_free(relpath);
-
-    /* Check if we have to migrate from the old file format */
-    if(filename == NULL) {
-        gchar *old_relpath = g_strdup_printf("xfce4/desktop/icons.screen%d.rc", 0);
-        filename = xfce_resource_lookup(XFCE_RESOURCE_CONFIG, old_relpath);
-        g_free(old_relpath);
-    }
-
-    /* Still nothing ? Just use the latest available file as fallback */
-    if(filename == NULL) {
-        filename = xfce_resource_lookup(XFCE_RESOURCE_CONFIG, "xfce4/desktop/icons.screen.latest.rc");
-    }
-
-    gboolean ret = FALSE;
-    if(filename != NULL) {
-        XfceRc *rcfile = xfce_rc_simple_open(filename, TRUE);
-
-        if (rcfile != NULL) {
-            gboolean has_group = FALSE;
-
-            /* Newer versions use the identifier rather than the icon label when
-             * possible */
-            const gchar *name = xfdesktop_icon_peek_label(XFDESKTOP_ICON(icon));
-            gchar *identifier = xfdesktop_icon_get_identifier(XFDESKTOP_ICON(icon));
-            if (xfce_rc_has_group(rcfile, XFDESKTOP_RC_VERSION_STAMP)
-                && identifier != NULL
-                && xfce_rc_has_group(rcfile, identifier))
-            {
-                xfce_rc_set_group(rcfile, identifier);
-                has_group = TRUE;
-            } else if (xfce_rc_has_group(rcfile, name)) {
-                xfce_rc_set_group(rcfile, name);
-                has_group = TRUE;
-            }
+update_icon_position(MonitorData *mdata, XfdesktopFileIcon *icon, gint row, gint col) {
+    xfdesktop_icon_set_position(XFDESKTOP_ICON(icon), row, col);
+
+    gchar *identifier = xfdesktop_icon_get_identifier(XFDESKTOP_ICON(icon));
+    guint64 last_seen = XFDESKTOP_IS_VOLUME_ICON(icon) ? g_get_real_time() : 0;
+    xfdesktop_icon_position_configs_set_icon_position(mdata->fmanager->position_configs,
+                                                      mdata->position_config,
+                                                      identifier,
+                                                      row,
+                                                      col,
+                                                      last_seen);
+    g_free(identifier);
 
-            if (has_group) {
-                *row = xfce_rc_read_int_entry(rcfile, "row", -1);
-                *col = xfce_rc_read_int_entry(rcfile, "col", -1);
-                if(*row >= 0 && *col >= 0)
-                    ret = TRUE;
-            }
-            xfce_rc_close(rcfile);
-
-            g_free(identifier);
-        }
+    GtkTreeIter iter;
+    if (xfdesktop_file_icon_model_get_icon_iter(mdata->fmanager->model, icon, &iter)) {
+        GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(mdata->fmanager->model), &iter);
+        gtk_tree_model_row_changed(GTK_TREE_MODEL(mdata->fmanager->model), path, &iter);
+        gtk_tree_path_free(path);
     }
+}
 
-    g_free(filename);
-
-    return ret;
+static void
+clear_icon_position(MonitorData *mdata, XfdesktopFileIcon *icon) {
+    xfdesktop_icon_set_position(XFDESKTOP_ICON(icon), -1, -1);
+    
+    gchar *identifier = xfdesktop_icon_get_identifier(XFDESKTOP_ICON(icon));
+    xfdesktop_icon_position_configs_remove_icon(mdata->fmanager->position_configs, mdata->position_config, identifier);
+    g_free(identifier);
 }
 
 static gint
@@ -1995,9 +2046,9 @@ static void
 xfdesktop_file_icon_manager_start_grid_resize(XfdesktopIconView *icon_view,
                                               gint new_rows,
                                               gint new_cols,
-                                              XfdesktopFileIconManager *fmanager)
+                                              MonitorData *mdata)
 {
-    if (!fmanager->ready) {
+    if (!mdata->fmanager->ready) {
         return;
     }
 
@@ -2005,39 +2056,35 @@ xfdesktop_file_icon_manager_start_grid_resize(XfdesktopIconView *icon_view,
     GQueue *pending_icons = g_queue_new();
 
     // Remove the model from the icon view so the changes we make here won't affect the view.
-    GtkTreeModel *model = xfdesktop_icon_view_get_model(icon_view);
     xfdesktop_icon_view_set_model(icon_view, NULL);
 
     GtkTreeIter iter;
-    if (gtk_tree_model_get_iter_first(model, &iter)) {
+    if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(mdata->filter), &iter)) {
         do {
-            XfdesktopIcon *icon = XFDESKTOP_ICON(xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, &iter));
+            XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(mdata->filter, &iter);
             gint16 row, col;
 
-            if(xfdesktop_file_icon_manager_get_cached_icon_position(fmanager,
-                                                                    XFDESKTOP_FILE_ICON(icon),
-                                                                    &row, &col))
-            {
+            if(xfdesktop_file_icon_manager_get_cached_icon_position(mdata->fmanager, icon, &row, &col)) {
                 // If we have a cached position, we assume it's authoritative, unless it's invalid.
                 gint pos = linear_pos(row, new_rows, col, new_cols);
                 if (pos >= 0) {
-                    xfdesktop_icon_set_position(icon, row, col);
+                    update_icon_position(mdata, icon, row, col);
                     g_hash_table_insert(placed_icons, GINT_TO_POINTER(pos), icon);
                 } else {
-                    xfdesktop_icon_set_position(icon, -1, -1);
+                    clear_icon_position(mdata, icon);
                 }
             } else {
                 // We'll try again after we've dealt with all the cached icons.
                 g_queue_push_tail(pending_icons, icon);
             }
-        } while (gtk_tree_model_iter_next(model, &iter));
+        } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(mdata->filter), &iter));
     }
 
-    XfdesktopIcon *pending_icon;
+    XfdesktopFileIcon *pending_icon;
     while ((pending_icon = g_queue_pop_head(pending_icons)) != NULL) {
         gint16 row, col;
 
-        if (xfdesktop_icon_get_position(pending_icon, &row, &col)) {
+        if (xfdesktop_icon_get_position(XFDESKTOP_ICON(pending_icon), &row, &col)) {
             // This icon was positioned pre-grid-resize, but didn't have a cached position
             // (perhaps it is new since we last used the new grid size), so we can attempt
             // to use its old position, but must allow another icon we've already placed
@@ -2045,10 +2092,10 @@ xfdesktop_file_icon_manager_start_grid_resize(XfdesktopIconView *icon_view,
             gint pos = linear_pos(row, new_rows, col, new_cols);
 
             if (pos >= 0 && g_hash_table_lookup(placed_icons, GINT_TO_POINTER(pos)) == NULL) {
-                xfdesktop_icon_set_position(pending_icon, row, col);
+                update_icon_position(mdata, pending_icon, row, col);
                 g_hash_table_insert(placed_icons, GINT_TO_POINTER(pos), pending_icon);
             } else {
-                xfdesktop_icon_set_position(pending_icon, -1, -1);
+                clear_icon_position(mdata, pending_icon);
             }
         }
     }
@@ -2060,26 +2107,26 @@ xfdesktop_file_icon_manager_start_grid_resize(XfdesktopIconView *icon_view,
 }
 
 static void
-xfdesktop_file_icon_manager_end_grid_resize(XfdesktopIconView *icon_view, XfdesktopFileIconManager *fmanager) {
-    if (fmanager->ready) {
+xfdesktop_file_icon_manager_end_grid_resize(XfdesktopIconView *icon_view, MonitorData *mdata) {
+    if (mdata->fmanager->ready) {
         // Re-set the model after the resize is done so the view can repopulate itself.
-        xfdesktop_icon_view_set_model(icon_view, GTK_TREE_MODEL(fmanager->filter));
+        xfdesktop_icon_view_set_model(icon_view, GTK_TREE_MODEL(mdata->filter));
     }
 }
 
 static void
 xfdesktop_file_icon_manager_refresh_icons(XfdesktopFileIconManager *fmanager)
 {
-    /* if a save is pending, flush icon positions */
-    if(fmanager->save_icons_id) {
-        g_source_remove(fmanager->save_icons_id);
-        fmanager->save_icons_id = 0;
-        xfdesktop_file_icon_manager_save_icons(fmanager);
-    }
-
     fmanager->ready = FALSE;
-    XfdesktopIconView *icon_view = xfdesktop_icon_view_holder_get_icon_view(fmanager->holder);
-    xfdesktop_icon_view_set_model(icon_view, NULL);
+
+    GHashTableIter iter;
+    g_hash_table_iter_init(&iter, fmanager->monitor_data);
+
+    MonitorData *mdata;
+    while (g_hash_table_iter_next(&iter, NULL, (gpointer)&mdata)) {
+        XfdesktopIconView *icon_view = xfdesktop_icon_view_holder_get_icon_view(mdata->holder);
+        xfdesktop_icon_view_set_model(icon_view, NULL);
+    }
     xfdesktop_file_icon_model_reload(fmanager->model);
 }
 
@@ -2087,22 +2134,28 @@ static GList *
 xfdesktop_file_icon_manager_get_selected_icons(XfdesktopFileIconManager *fmanager)
 {
     GList *selected_icons = NULL;
-    GList *selected = xfdesktop_icon_view_get_selected_items(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder));
-    for (GList *l = selected; l != NULL; l = l->next) {
-        GtkTreePath *path = (GtkTreePath *)l->data;
-        GtkTreeIter iter;
 
-        if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fmanager->filter), &iter, path)) {
-            XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, &iter);
+    GHashTableIter hiter;
+    g_hash_table_iter_init(&hiter, fmanager->monitor_data);
 
-            if (icon != NULL) {
-                selected_icons = g_list_prepend(selected_icons, icon);
+    MonitorData *mdata;
+    while (g_hash_table_iter_next(&hiter, NULL, (gpointer)&mdata)) {
+
+        GList *selected = xfdesktop_icon_view_get_selected_items(xfdesktop_icon_view_holder_get_icon_view(mdata->holder));
+        for (GList *l = selected; l != NULL; l = l->next) {
+            GtkTreePath *path = (GtkTreePath *)l->data;
+            GtkTreeIter iter;
+
+            if (gtk_tree_model_get_iter(GTK_TREE_MODEL(mdata->filter), &iter, path)) {
+                XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(mdata->filter, &iter);
+                if (icon != NULL) {
+                    selected_icons = g_list_prepend(selected_icons, icon);
+                }
             }
         }
+        g_list_free_full(selected, (GDestroyNotify)gtk_tree_path_free);
     }
 
-    g_list_free(selected);
-
     return selected_icons;
 }
 
@@ -2112,7 +2165,7 @@ xfdesktop_file_icon_manager_key_press(GtkWidget *widget, GdkEventKey *evt, Xfdes
         case GDK_KEY_Delete:
         case GDK_KEY_KP_Delete: {
             gboolean force_delete = evt->state & GDK_SHIFT_MASK;
-            xfdesktop_file_icon_manager_delete_selected(fmanager, force_delete);
+            xfdesktop_file_icon_manager_delete_selected(fmanager, widget, force_delete);
             break;
         }
 
@@ -2202,28 +2255,34 @@ xfdesktop_file_icon_manager_key_press(GtkWidget *widget, GdkEventKey *evt, Xfdes
 
 static void
 xfdesktop_file_icon_manager_clipboard_changed(XfdesktopClipboardManager *cmanager, XfdesktopFileIconManager *fmanager) {
-    XfdesktopIconView *icon_view = xfdesktop_icon_view_holder_get_icon_view(fmanager->holder);
+    GHashTableIter hiter;
+    g_hash_table_iter_init(&hiter, fmanager->monitor_data);
 
-    TRACE("entering");
+    MonitorData *mdata;
+    while (g_hash_table_iter_next(&hiter, NULL, (gpointer)&mdata)) {
+        XfdesktopIconView *icon_view = xfdesktop_icon_view_holder_get_icon_view(mdata->holder);
 
-    GtkTreeIter iter;
-    if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(fmanager->filter), &iter)) {
-        do {
-            XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, &iter);
-            if (icon != NULL) {
-                gboolean is_cut = xfdesktop_clipboard_manager_has_cutted_file(clipboard_manager, icon);
-                xfdesktop_icon_view_set_item_sensitive(icon_view, &iter, !is_cut);
-            }
-        } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(fmanager->filter), &iter));
+        TRACE("entering");
+
+        GtkTreeIter iter;
+        if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(mdata->filter), &iter)) {
+            do {
+                XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(mdata->filter, &iter);
+                if (icon != NULL) {
+                    gboolean is_cut = xfdesktop_clipboard_manager_has_cutted_file(clipboard_manager, icon);
+                    xfdesktop_icon_view_set_item_sensitive(icon_view, &iter, !is_cut);
+                }
+            } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(mdata->filter), &iter));
+        }
     }
 }
 
 static GdkDragAction
 xfdesktop_file_icon_manager_drag_actions_get(XfdesktopIconView *icon_view,
                                              GtkTreeIter *iter,
-                                             XfdesktopFileIconManager *fmanager)
+                                             MonitorData *mdata)
 {
-    XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, iter);
+    XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(mdata->filter, iter);
     return icon != NULL ? xfdesktop_icon_get_allowed_drag_actions(XFDESKTOP_ICON(icon)) : 0;
 }
 
@@ -2231,9 +2290,9 @@ static GdkDragAction
 xfdesktop_file_icon_manager_drop_actions_get(XfdesktopIconView *icon_view,
                                              GtkTreeIter *iter,
                                              GdkDragAction *suggested_action,
-                                             XfdesktopFileIconManager *fmanager)
+                                             MonitorData *mdata)
 {
-    XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, iter);
+    XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(mdata->filter, iter);
     return icon != NULL ? xfdesktop_icon_get_allowed_drop_actions(XFDESKTOP_ICON(icon), suggested_action) : 0;
 }
 
@@ -2243,12 +2302,12 @@ xfdesktop_file_icon_manager_drag_drop_items(XfdesktopIconView *icon_view,
                                             GtkTreeIter *iter,
                                             GList *dropped_item_paths,
                                             GdkDragAction action,
-                                            XfdesktopFileIconManager *fmanager)
+                                            MonitorData *mdata)
 {
     g_return_val_if_fail(iter != NULL, FALSE);
     g_return_val_if_fail(dropped_item_paths != NULL, FALSE);
 
-    XfdesktopFileIcon *drop_icon = xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, iter);
+    XfdesktopFileIcon *drop_icon = xfdesktop_file_icon_model_filter_get_icon(mdata->filter, iter);
     g_return_val_if_fail(drop_icon != NULL, FALSE);
 
     GList *dropped_icons = NULL;
@@ -2256,8 +2315,8 @@ xfdesktop_file_icon_manager_drag_drop_items(XfdesktopIconView *icon_view,
         GtkTreePath *path = (GtkTreePath *)l->data;
         GtkTreeIter drop_iter;
 
-        if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fmanager->filter), &drop_iter, path)) {
-            XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, &drop_iter);
+        if (gtk_tree_model_get_iter(GTK_TREE_MODEL(mdata->filter), &drop_iter, path)) {
+            XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(mdata->filter, &drop_iter);
 
             if (icon != NULL) {
                 dropped_icons = g_list_prepend(dropped_icons, icon);
@@ -2282,15 +2341,15 @@ xfdesktop_file_icon_manager_drag_drop_item(XfdesktopIconView *icon_view,
                                            gint row,
                                            gint col,
                                            guint time_,
-                                           XfdesktopFileIconManager *fmanager)
+                                           MonitorData *mdata)
 {
     TRACE("entering");
 
     XfdesktopFileIcon *drop_icon = iter != NULL
-        ? xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, iter)
+        ? xfdesktop_file_icon_model_filter_get_icon(mdata->filter, iter)
         : NULL;
     GtkWidget *widget = GTK_WIDGET(icon_view);
-    GdkAtom target = gtk_drag_dest_find_target(widget, context, fmanager->drop_targets);
+    GdkAtom target = gtk_drag_dest_find_target(widget, context, mdata->fmanager->drop_targets);
     if (target == GDK_NONE) {
         return FALSE;
     } else if (target == gdk_atom_intern("XdndDirectSave0", FALSE)) {
@@ -2308,7 +2367,7 @@ xfdesktop_file_icon_manager_drag_drop_item(XfdesktopIconView *icon_view,
             source_file = xfdesktop_file_icon_peek_file(XFDESKTOP_FILE_ICON(drop_icon));
 
         } else
-            source_file = fmanager->folder;
+            source_file = mdata->fmanager->folder;
 
         gboolean ret = FALSE;
         guchar *prop_val = NULL;
@@ -2435,18 +2494,18 @@ xfdesktop_file_icon_manager_drag_item_data_received(XfdesktopIconView *icon_view
                                                     GtkSelectionData *data,
                                                     guint info,
                                                     guint time_,
-                                                    XfdesktopFileIconManager *fmanager)
+                                                    MonitorData *mdata)
 {
     TRACE("entering");
 
     gboolean copy_only = TRUE, drop_ok = FALSE;
     XfdesktopFileIcon *drop_icon = iter != NULL
-        ? xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, iter)
+        ? xfdesktop_file_icon_model_filter_get_icon(mdata->filter, iter)
         : NULL;
     GdkDragAction action = gdk_drag_context_get_selected_action(context);
 
     if (action == GDK_ACTION_ASK) {
-        action = xfdesktop_file_icon_manager_drag_drop_ask(icon_view, context, iter, row, col, time_, fmanager);
+        action = xfdesktop_file_icon_manager_drag_drop_ask(icon_view, context, iter, row, col, time_, mdata->fmanager);
         if(action == 0) {
             gtk_drag_finish(context, FALSE, FALSE, time_);
             return;
@@ -2476,7 +2535,7 @@ xfdesktop_file_icon_manager_drag_item_data_received(XfdesktopIconView *icon_view
             if(finfo != NULL && g_file_info_get_file_type(finfo) == G_FILE_TYPE_DIRECTORY)
                 source_file = xfdesktop_file_icon_peek_file(XFDESKTOP_FILE_ICON(drop_icon));
         } else
-            source_file = fmanager->folder;
+            source_file = mdata->fmanager->folder;
 
         gchar *exo_desktop_item_edit = g_find_program_in_path("exo-desktop-item-edit");
         if(source_file && exo_desktop_item_edit) {
@@ -2499,7 +2558,7 @@ xfdesktop_file_icon_manager_drag_item_data_received(XfdesktopIconView *icon_view
                 myargv[i++] = cwd;
                 myargv[i++] = NULL;
 
-                drop_ok = xfce_spawn(fmanager->gscreen, NULL, myargv,
+                drop_ok = xfce_spawn(mdata->fmanager->gscreen, NULL, myargv,
                                      NULL, G_SPAWN_SEARCH_PATH, TRUE,
                                      gtk_get_current_event_time(),
                                      NULL, TRUE, NULL);
@@ -2572,17 +2631,17 @@ xfdesktop_file_icon_manager_drag_item_data_received(XfdesktopIconView *icon_view
 
         GList *file_list = xfdesktop_file_utils_file_list_from_string((const gchar *)gtk_selection_data_get_data(data));
         if(file_list) {
-            GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(xfdesktop_icon_view_holder_get_icon_view(fmanager->holder)));
+            GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(icon_view));
 
             if(tinfo && xfdesktop_file_utils_file_is_executable(tinfo)) {
-                drop_ok = xfdesktop_file_utils_execute(fmanager->folder,
+                drop_ok = xfdesktop_file_utils_execute(mdata->fmanager->folder,
                                                        tfile, file_list,
-                                                       fmanager->gscreen,
+                                                       mdata->fmanager->gscreen,
                                                        GTK_WINDOW(toplevel));
             } else if(tfile && g_file_has_uri_scheme(tfile, "trash")) {
                 /* move files to the trash */
                 xfdesktop_file_utils_trash_files(file_list,
-                                                 fmanager->gscreen,
+                                                 mdata->fmanager->gscreen,
                                                  GTK_WINDOW(toplevel));
             } else {
                 gboolean dest_is_volume = drop_icon && XFDESKTOP_IS_VOLUME_ICON(drop_icon);
@@ -2598,7 +2657,7 @@ xfdesktop_file_icon_manager_drag_item_data_received(XfdesktopIconView *icon_view
                 if(tinfo && g_file_info_get_file_type(tinfo) == G_FILE_TYPE_DIRECTORY) {
                     base_dest_file = g_object_ref(tfile);
                 } else {
-                    base_dest_file = g_object_ref(fmanager->folder);
+                    base_dest_file = g_object_ref(mdata->fmanager->folder);
                 }
 
                 gint cur_row = row;
@@ -2623,7 +2682,7 @@ xfdesktop_file_icon_manager_drag_item_data_received(XfdesktopIconView *icon_view
                             // correctly (when the GFileMonitor gets notified about them), we need to store a little
                             // bit of data about the new files based on the drop location.
                             GFile *file = g_file_get_child(base_dest_file, dest_basename);
-                            xfdesktop_file_icon_model_add_pending_new_file(fmanager->model, file, cur_row, cur_col);
+                            xfdesktop_file_icon_model_add_pending_new_file(mdata->fmanager->model, file, cur_row, cur_col);
                             if (!xfdesktop_icon_view_get_next_free_grid_position(icon_view,
                                                                                  cur_row, cur_col,
                                                                                  &cur_row, &cur_col))
@@ -2641,7 +2700,7 @@ xfdesktop_file_icon_manager_drag_item_data_received(XfdesktopIconView *icon_view
 
                 if(dest_file_list) {
                     dest_file_list = g_list_reverse(dest_file_list);
-                    xfdesktop_file_utils_transfer_files(action, file_list, dest_file_list, fmanager->gscreen);
+                    xfdesktop_file_utils_transfer_files(action, file_list, dest_file_list, mdata->fmanager->gscreen);
                     drop_ok = TRUE;
                 }
 
@@ -2666,7 +2725,7 @@ xfdesktop_file_icon_manager_drag_data_get(GtkWidget *icon_view,
                                           GtkSelectionData *data,
                                           guint info,
                                           guint time_,
-                                          XfdesktopFileIconManager *fmanager)
+                                          MonitorData *mdata)
 {
     if (info == TARGET_TEXT_URI_LIST) {
         GList *selected_items = xfdesktop_icon_view_get_selected_items(XFDESKTOP_ICON_VIEW(icon_view));
@@ -2679,8 +2738,8 @@ xfdesktop_file_icon_manager_drag_data_get(GtkWidget *icon_view,
                 GtkTreePath *path = (GtkTreePath *)l->data;
                 GtkTreeIter iter;
 
-                if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fmanager->filter), &iter, path)) {
-                    XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, &iter);
+                if (gtk_tree_model_get_iter(GTK_TREE_MODEL(mdata->filter), &iter, path)) {
+                    XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(mdata->filter, &iter);
 
                     if (icon != NULL) {
                         GFile *file = xfdesktop_file_icon_peek_file(icon);
@@ -2710,14 +2769,14 @@ xfdesktop_file_icon_manager_drop_propose_action(XfdesktopIconView *icon_view,
                                                 GdkDragAction action,
                                                 GtkSelectionData *data,
                                                 guint info,
-                                                XfdesktopFileIconManager *fmanager)
+                                                MonitorData *mdata)
 {
     if (info == TARGET_TEXT_URI_LIST && action == GDK_ACTION_COPY
         && (gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE) != 0)
     {
 
         XfdesktopFileIcon *drop_icon = iter != NULL
-            ? xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, iter)
+            ? xfdesktop_file_icon_model_filter_get_icon(mdata->filter, iter)
             : NULL;
         GFileInfo *tinfo = NULL;
         GFile *tfile = NULL;
@@ -2760,7 +2819,7 @@ xfdesktop_file_icon_manager_drop_propose_action(XfdesktopIconView *icon_view,
             if(tinfo) {
                 base_dest_file = g_object_ref(tfile);
             } else {
-                base_dest_file = g_object_ref(fmanager->folder);
+                base_dest_file = g_object_ref(mdata->fmanager->folder);
             }
 
             /* dropping on ourselves? */
@@ -2817,8 +2876,15 @@ static void
 model_ready(XfdesktopFileIconModel *fmodel, XfdesktopFileIconManager *fmanager) {
     DBG("entering");
     fmanager->ready = TRUE;
-    XfdesktopIconView *icon_view = xfdesktop_icon_view_holder_get_icon_view(fmanager->holder);
-    xfdesktop_icon_view_set_model(icon_view, GTK_TREE_MODEL(fmanager->filter));
+
+    GHashTableIter iter;
+    g_hash_table_iter_init(&iter, fmanager->monitor_data);
+
+    MonitorData *mdata;
+    while (g_hash_table_iter_next(&iter, NULL, (gpointer)&mdata)) {
+        XfdesktopIconView *icon_view = xfdesktop_icon_view_holder_get_icon_view(mdata->holder);
+        xfdesktop_icon_view_set_model(icon_view, GTK_TREE_MODEL(mdata->filter));
+    }
 }
 
 static void
@@ -2873,9 +2939,9 @@ xfdesktop_file_icon_manager_icon_moved(XfdesktopIconView *icon_view,
                                        GtkTreeIter *iter,
                                        gint new_row,
                                        gint new_col,
-                                       XfdesktopFileIconManager *fmanager)
+                                       MonitorData *mdata)
 {
-    XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, iter);
+    XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(mdata->filter, iter);
 
     if (G_LIKELY(icon != NULL)) {
         gint16 old_row, old_col;
@@ -2884,30 +2950,21 @@ xfdesktop_file_icon_manager_icon_moved(XfdesktopIconView *icon_view,
             || old_row != new_row
             || old_col != new_col)
         {
-            xfdesktop_icon_set_position(XFDESKTOP_ICON(icon), new_row, new_col);
-            xfdesktop_file_icon_manager_save_icons(fmanager);
+            update_icon_position(mdata, icon, new_row, new_col);
         }
     }
 }
 
 static void
-xfdesktop_file_icon_manager_icon_activated(XfdesktopIconView *icon_view, XfdesktopFileIconManager *fmanager) {
-    GList *selected = xfdesktop_icon_view_get_selected_items(icon_view);
-
-    for (GList *l = selected; l != NULL; l = l->next) {
-        GtkTreePath *path = (GtkTreePath *)l->data;
-        GtkTreeIter iter;
+xfdesktop_file_icon_manager_activate_selected(GtkWidget *widget, XfdesktopFileIconManager *fmanager) {
+    GList *selected_icons = xfdesktop_file_icon_manager_get_selected_icons(fmanager);
 
-        if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fmanager->filter), &iter, path)) {
-            XfdesktopFileIcon *icon = xfdesktop_file_icon_model_filter_get_icon(fmanager->filter, &iter);
-            if (icon != NULL) {
-                xfdesktop_icon_activate(XFDESKTOP_ICON(icon),
-                                        GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(icon_view))));
-            }
-        }
+    for (GList *l = selected_icons; l != NULL; l = l->next) {
+        XfdesktopFileIcon *icon = XFDESKTOP_FILE_ICON(l->data);
+        xfdesktop_icon_activate(XFDESKTOP_ICON(icon), toplevel_window_for_widget(widget));
     }
 
-    g_list_free(selected);
+    g_list_free(selected_icons);
 }
 
 
diff --git a/src/xfdesktop-file-icon-model-filter.c b/src/xfdesktop-file-icon-model-filter.c
index cbba30b57a1f6ef5da15a5f9bf8ae847ff2ba236..a1ba1e9d8dcd52592f0c0ab163949d1504c685bb 100644
--- a/src/xfdesktop-file-icon-model-filter.c
+++ b/src/xfdesktop-file-icon-model-filter.c
@@ -18,9 +18,13 @@
  *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
+#include <glib-object.h>
+
 #include "common/xfdesktop-common.h"
 #include "xfdesktop-file-icon-model-filter.h"
 #include "xfdesktop-file-icon-model.h"
+#include "xfdesktop-icon-position-configs.h"
+#include "xfdesktop-icon.h"
 #include "xfdesktop-regular-file-icon.h"
 #include "xfdesktop-special-file-icon.h"
 #include "xfdesktop-volume-icon.h"
@@ -29,6 +33,8 @@ struct _XfdesktopFileIconModelFilter {
     GtkTreeModelFilter parent;
 
     XfconfChannel *channel;
+    XfdesktopIconPositionConfigs *position_configs;
+    XfwMonitor *monitor;
 
     gboolean show_special_home;
     gboolean show_special_filesystem;
@@ -43,6 +49,8 @@ struct _XfdesktopFileIconModelFilter {
 enum {
     PROP0,
     PROP_CHANNEL,
+    PROP_POSITION_CONFIGS,
+    PROP_MONITOR,
     PROP_SHOW_HOME,
     PROP_SHOW_FILESYSTEM,
     PROP_SHOW_TRASH,
@@ -111,6 +119,19 @@ xfdesktop_file_icon_model_filter_class_init(XfdesktopFileIconModelFilterClass *k
                                                         "xfconf channel",
                                                         XFCONF_TYPE_CHANNEL,
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property(gobject_class,
+                                    PROP_POSITION_CONFIGS,
+                                    g_param_spec_pointer("position-configs",
+                                                         "position-configs",
+                                                         "XfdesktopIconPositionConfigs",
+                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property(gobject_class,
+                                    PROP_MONITOR,
+                                    g_param_spec_object("monitor",
+                                                        "monitor",
+                                                        "xfw monitor",
+                                                        XFW_TYPE_MONITOR,
+                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
     g_object_class_install_property(gobject_class,
                                     PROP_SHOW_HOME,
                                     g_param_spec_boolean("show-home",
@@ -207,6 +228,14 @@ xfdesktop_file_icon_model_filter_set_property(GObject *object, guint property_id
             filter->channel = g_value_dup_object(value);
             break;
 
+        case PROP_POSITION_CONFIGS:
+            filter->position_configs = g_value_get_pointer(value);
+            break;
+
+        case PROP_MONITOR:
+            filter->monitor = g_value_dup_object(value);
+            break;
+
         case PROP_SHOW_HOME:
             filter->show_special_home = g_value_get_boolean(value);
             gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter));
@@ -262,6 +291,14 @@ xfdesktop_file_icon_model_filter_get_property(GObject *object, guint property_id
             g_value_set_object(value, filter->channel);
             break;
 
+        case PROP_POSITION_CONFIGS:
+            g_value_set_object(value, filter->position_configs);
+            break;
+
+        case PROP_MONITOR:
+            g_value_set_object(value, filter->monitor);
+            break;
+
         case PROP_SHOW_HOME:
             g_value_set_boolean(value, filter->show_special_home);
             break;
@@ -311,13 +348,22 @@ static gboolean
 xfdesktop_file_icon_model_filter_visible(GtkTreeModelFilter *tmfilter, GtkTreeModel *child_model, GtkTreeIter *child_iter) {
     XfdesktopFileIconModelFilter *filter = XFDESKTOP_FILE_ICON_MODEL_FILTER(tmfilter);
     XfdesktopFileIcon *icon = xfdesktop_file_icon_model_get_icon(XFDESKTOP_FILE_ICON_MODEL(child_model), child_iter);
-    return icon != NULL
-        && (
-            (XFDESKTOP_IS_REGULAR_FILE_ICON(icon) && is_regular_file_visible(filter, XFDESKTOP_REGULAR_FILE_ICON(icon)))
-            || (XFDESKTOP_IS_SPECIAL_FILE_ICON(icon) && is_special_file_visible(filter, XFDESKTOP_SPECIAL_FILE_ICON(icon)))
-            || (XFDESKTOP_IS_VOLUME_ICON(icon) && is_volume_visible(filter, XFDESKTOP_VOLUME_ICON(icon)))
-        )
-        && GTK_TREE_MODEL_FILTER_CLASS(xfdesktop_file_icon_model_filter_parent_class)->visible(tmfilter, child_model, child_iter);
+    if (icon != NULL) {
+        gchar *icon_id = xfdesktop_icon_get_identifier(XFDESKTOP_ICON(icon));
+        XfwMonitor *monitor = NULL;
+        gboolean found = xfdesktop_icon_position_configs_lookup(filter->position_configs, icon_id, &monitor, NULL, NULL);
+        g_free(icon_id);
+
+        return ((found && monitor == filter->monitor) || (!found && xfw_monitor_is_primary(filter->monitor)))
+            && (
+                (XFDESKTOP_IS_REGULAR_FILE_ICON(icon) && is_regular_file_visible(filter, XFDESKTOP_REGULAR_FILE_ICON(icon)))
+                || (XFDESKTOP_IS_SPECIAL_FILE_ICON(icon) && is_special_file_visible(filter, XFDESKTOP_SPECIAL_FILE_ICON(icon)))
+                || (XFDESKTOP_IS_VOLUME_ICON(icon) && is_volume_visible(filter, XFDESKTOP_VOLUME_ICON(icon)))
+            )
+            && GTK_TREE_MODEL_FILTER_CLASS(xfdesktop_file_icon_model_filter_parent_class)->visible(tmfilter, child_model, child_iter);
+    } else {
+        return FALSE;
+    }
 }
 
 static gboolean
@@ -356,10 +402,19 @@ is_regular_file_visible(XfdesktopFileIconModelFilter *filter, XfdesktopRegularFi
 }
 
 XfdesktopFileIconModelFilter *
-xfdesktop_file_icon_model_filter_new(XfconfChannel *channel, XfdesktopFileIconModel *child) {
+xfdesktop_file_icon_model_filter_new(XfconfChannel *channel,
+                                     XfdesktopIconPositionConfigs *position_configs,
+                                     XfwMonitor *monitor,
+                                     XfdesktopFileIconModel *child)
+{
+    g_return_val_if_fail(XFCONF_IS_CHANNEL(channel), NULL);
+    g_return_val_if_fail(position_configs != NULL, NULL);
+    g_return_val_if_fail(XFW_IS_MONITOR(monitor), NULL);
     g_return_val_if_fail(XFDESKTOP_IS_FILE_ICON_MODEL(child), NULL);
     return g_object_new(XFDESKTOP_TYPE_FILE_ICON_MODEL_FILTER,
                         "channel", channel,
+                        "position-configs", position_configs,
+                        "monitor", monitor,
                         "child-model", child,
                         NULL);
 }
diff --git a/src/xfdesktop-file-icon-model-filter.h b/src/xfdesktop-file-icon-model-filter.h
index 3947dabaef519511817c27426b9664ced119e245..1a202a2d9e3bcb27f0f7bd18ece126252bb5f229 100644
--- a/src/xfdesktop-file-icon-model-filter.h
+++ b/src/xfdesktop-file-icon-model-filter.h
@@ -23,9 +23,11 @@
 
 #include <gtk/gtk.h>
 #include <xfconf/xfconf.h>
+#include <libxfce4windowing/libxfce4windowing.h>
 
 #include "xfdesktop-file-icon-model.h"
 #include "xfdesktop-file-icon.h"
+#include "xfdesktop-icon-position-configs.h"
 
 G_BEGIN_DECLS
 
@@ -33,6 +35,8 @@ G_DECLARE_FINAL_TYPE(XfdesktopFileIconModelFilter, xfdesktop_file_icon_model_fil
 #define XFDESKTOP_TYPE_FILE_ICON_MODEL_FILTER (xfdesktop_file_icon_model_filter_get_type())
 
 XfdesktopFileIconModelFilter *xfdesktop_file_icon_model_filter_new(XfconfChannel *channel,
+                                                                   XfdesktopIconPositionConfigs *position_configs,
+                                                                   XfwMonitor *monitor,
                                                                    XfdesktopFileIconModel *child);
 
 XfdesktopFileIcon *xfdesktop_file_icon_model_filter_get_icon(XfdesktopFileIconModelFilter *filter,
diff --git a/src/xfdesktop-file-icon-model.c b/src/xfdesktop-file-icon-model.c
index b7e26fd5c72cf99e6660af04aa1f119b0663fc77..ea9d15c831ce79270e46800a568ecc5d1bcafb83 100644
--- a/src/xfdesktop-file-icon-model.c
+++ b/src/xfdesktop-file-icon-model.c
@@ -18,6 +18,7 @@
  *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
+#include "libxfce4windowing/libxfce4windowing.h"
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -261,8 +262,8 @@ xfdesktop_file_icon_model_class_init(XfdesktopFileIconModelClass *klass)
                                                       0,
                                                       NULL,
                                                       NULL,
-                                                      xfdesktop_marshal_BOOLEAN__OBJECT_POINTER_POINTER,
-                                                      G_TYPE_BOOLEAN,
+                                                      xfdesktop_marshal_OBJECT__OBJECT_POINTER_POINTER,
+                                                      XFW_TYPE_MONITOR,
                                                       3,
                                                       XFDESKTOP_TYPE_FILE_ICON,
                                                       G_TYPE_POINTER,
@@ -542,10 +543,11 @@ check_create_desktop_folder(XfdesktopFileIconModel *fmodel) {
 
 static void
 add_icon(XfdesktopFileIconModel *fmodel, XfdesktopFileIcon *icon) {
-    gboolean pos_valid = FALSE;
+    XfwMonitor *monitor = NULL;
     gint16 row = -1, col = -1;
-    g_signal_emit(fmodel, signals[SIG_ICON_POSITION_REQUEST], 0, icon, &row, &col, &pos_valid);
-    if (pos_valid) {
+    g_signal_emit(fmodel, signals[SIG_ICON_POSITION_REQUEST], 0, icon, &row, &col, &monitor);
+    xfdesktop_icon_set_monitor(XFDESKTOP_ICON(icon), monitor);
+    if (row != -1 && col != -1) {
         xfdesktop_icon_set_position(XFDESKTOP_ICON(icon), row, col);
     }
 
diff --git a/src/xfdesktop-icon.c b/src/xfdesktop-icon.c
index 61d32a5e840f3c01d21844ef8287d318c6e97f3d..2a994242bbe3fe63174dee2f4da13c2fffab7624 100644
--- a/src/xfdesktop-icon.c
+++ b/src/xfdesktop-icon.c
@@ -18,6 +18,7 @@
  *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
+#include "libxfce4windowing/libxfce4windowing.h"
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -30,10 +31,10 @@
 #include <gobject/gmarshal.h>
 
 #include "xfdesktop-icon.h"
-#include "xfdesktop-marshal.h"
 
 struct _XfdesktopIconPrivate
 {
+    XfwMonitor *monitor;
     gint16 row;
     gint16 col;
 };
@@ -90,17 +91,41 @@ xfdesktop_icon_init(XfdesktopIcon *icon)
     icon->priv->col = -1;
 }
 
-void
+gboolean
+xfdesktop_icon_set_monitor(XfdesktopIcon *icon, XfwMonitor *monitor) {
+    g_return_val_if_fail(XFDESKTOP_IS_ICON(icon), FALSE);
+    g_return_val_if_fail(monitor == NULL || XFW_IS_MONITOR(monitor), FALSE);
+
+    if (icon->priv->monitor != monitor) {
+        icon->priv->monitor = monitor;
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+XfwMonitor *
+xfdesktop_icon_get_monitor(XfdesktopIcon *icon) {
+    g_return_val_if_fail(XFDESKTOP_IS_ICON(icon), NULL);
+    return icon->priv->monitor;
+}
+
+gboolean
 xfdesktop_icon_set_position(XfdesktopIcon *icon,
                             gint16 row,
                             gint16 col)
 {
-    g_return_if_fail(XFDESKTOP_IS_ICON(icon));
-
-    icon->priv->row = row;
-    icon->priv->col = col;
+    g_return_val_if_fail(XFDESKTOP_IS_ICON(icon), FALSE);
+    g_return_val_if_fail((row >= 0 && col >= 0) || (row == -1 && col == -1), FALSE);
 
-    g_signal_emit(G_OBJECT(icon), __signals[SIG_POS_CHANGED], 0, NULL);
+    if (row != icon->priv->row || col != icon->priv->col) {
+        icon->priv->row = row;
+        icon->priv->col = col;
+        g_signal_emit(G_OBJECT(icon), __signals[SIG_POS_CHANGED], 0, NULL);
+        return TRUE;
+    } else {
+        return FALSE;
+    }
 }
 
 gboolean
@@ -110,10 +135,13 @@ xfdesktop_icon_get_position(XfdesktopIcon *icon,
 {
     g_return_val_if_fail(XFDESKTOP_IS_ICON(icon) && row && col, FALSE);
 
-    *row = icon->priv->row;
-    *col = icon->priv->col;
-
-    return TRUE;
+    if (icon->priv->row != -1 && icon->priv->col != -1) {
+        *row = icon->priv->row;
+        *col = icon->priv->col;
+        return TRUE;
+    } else {
+        return FALSE;
+    }
 }
 
 /*< required >*/
diff --git a/src/xfdesktop-icon.h b/src/xfdesktop-icon.h
index a9dfaccd4eb37c8ed0b7a0b5d2e11a4bb711fcf5..ccbe2b8988196155d7c9156838a0a5f7949e294a 100644
--- a/src/xfdesktop-icon.h
+++ b/src/xfdesktop-icon.h
@@ -22,6 +22,7 @@
 #define __XFDESKTOP_ICON_H__
 
 #include <gtk/gtk.h>
+#include <libxfce4windowing/libxfce4windowing.h>
 
 G_BEGIN_DECLS
 
@@ -75,6 +76,10 @@ struct _XfdesktopIconClass
 
 GType xfdesktop_icon_get_type(void) G_GNUC_CONST;
 
+gboolean xfdesktop_icon_set_monitor(XfdesktopIcon *icon,
+                                    XfwMonitor *monitor);
+XfwMonitor *xfdesktop_icon_get_monitor(XfdesktopIcon *icon);
+
 /* xfdesktop virtual function accessors */
 
 const gchar *xfdesktop_icon_peek_label(XfdesktopIcon *icon);
@@ -83,9 +88,9 @@ const gchar *xfdesktop_icon_peek_tooltip(XfdesktopIcon *icon);
 /* returns a unique identifier for the icon, free when done using it */
 gchar *xfdesktop_icon_get_identifier(XfdesktopIcon *icon);
 
-void xfdesktop_icon_set_position(XfdesktopIcon *icon,
-                                 gint16 row,
-                                 gint16 col);
+gboolean xfdesktop_icon_set_position(XfdesktopIcon *icon,
+                                     gint16 row,
+                                     gint16 col);
 gboolean xfdesktop_icon_get_position(XfdesktopIcon *icon,
                                      gint16 *row,
                                      gint16 *col);
diff --git a/src/xfdesktop-monitor-chooser-ui.glade b/src/xfdesktop-monitor-chooser-ui.glade
new file mode 100644
index 0000000000000000000000000000000000000000..251fe3491270a0e11c799f211a7071d2f36ba3f3
--- /dev/null
+++ b/src/xfdesktop-monitor-chooser-ui.glade
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.40.0 -->
+<interface>
+  <requires lib="gtk+" version="3.24"/>
+  <object class="GtkImage" id="img_apply">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="icon-name">gtk-apply</property>
+  </object>
+  <object class="GtkListStore" id="monitor_list">
+    <columns>
+      <!-- column-name Monitors -->
+      <column type="gchararray"/>
+      <!-- column-name Position Config -->
+      <column type="gpointer"/>
+    </columns>
+  </object>
+  <object class="GtkDialog" id="monitor_candidates_chooser">
+    <property name="can-focus">False</property>
+    <property name="icon-name">org.xfce.xfdesktop</property>
+    <property name="type-hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox">
+        <property name="can-focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox">
+            <property name="can-focus">False</property>
+            <property name="layout-style">end</property>
+            <child>
+              <object class="GtkButton" id="btn_apply">
+                <property name="label" translatable="yes">Apply</property>
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="receives-default">True</property>
+                <property name="image">img_apply</property>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="margin-start">6</property>
+            <property name="margin-end">6</property>
+            <property name="margin-top">12</property>
+            <property name="margin-bottom">6</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="monitor_question_label">
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="use-markup">True</property>
+                <property name="xalign">0</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkRadioButton" id="radio_auto_assign">
+                <property name="label" translatable="yes">Allow Xfce to auto-assign the best match</property>
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="receives-default">False</property>
+                <property name="active">True</property>
+                <property name="draw-indicator">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkRadioButton" id="radio_select_monitor">
+                <property name="label" translatable="yes">Select from existing monitor configurations:</property>
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="receives-default">False</property>
+                <property name="active">True</property>
+                <property name="draw-indicator">True</property>
+                <property name="group">radio_auto_assign</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkTreeView" id="monitor_list_view">
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="model">monitor_list</property>
+                <property name="headers-visible">False</property>
+                <property name="search-column">0</property>
+                <property name="enable-grid-lines">horizontal</property>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection"/>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkCheckButton" id="chk_always_auto_assign">
+                <property name="label" translatable="yes">Always auto-assign</property>
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="receives-default">False</property>
+                <property name="draw-indicator">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">4</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-3">btn_apply</action-widget>
+    </action-widgets>
+  </object>
+</interface>
diff --git a/src/xfdesktop-monitor-chooser-ui.gresource.xml b/src/xfdesktop-monitor-chooser-ui.gresource.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5c831b97b254fff9a18480d9d234ff363988284d
--- /dev/null
+++ b/src/xfdesktop-monitor-chooser-ui.gresource.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/org/xfce/xfdesktop/settings">
+    <file>xfdesktop-monitor-chooser-ui.glade</file>
+  </gresource>
+</gresources>