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>