Hello community, here is the log from the commit of package nemo for openSUSE:Factory checked in at 2016-03-16 10:35:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/nemo (Old) and /work/SRC/openSUSE:Factory/.nemo.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "nemo" Changes: -------- --- /work/SRC/openSUSE:Factory/nemo/nemo.changes 2016-01-21 23:41:51.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.nemo.new/nemo.changes 2016-03-16 10:35:09.000000000 +0100 @@ -1,0 +2,15 @@ +Wed Mar 9 18:09:32 UTC 2016 - [email protected] + +- Update to 2.8.7: + * Improve context menu toggle: + - shows separate distinct regions of the menu item now; + - tooltip manifests as right-justified text next to the toggle + icon. + * Use g_strcmp0 instead of unsafe strcmp. + * file: Don't crash when the original file path has reserved + characters. + * file-operations: Make sure to use correct filename when + restoring from Trash. + * file-utils: Ensure directories exist before restoring from trash. + +------------------------------------------------------------------- Old: ---- nemo-2.8.6.tar.gz New: ---- nemo-2.8.7.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ nemo.spec ++++++ --- /var/tmp/diff_new_pack.QfuY8x/_old 2016-03-16 10:35:10.000000000 +0100 +++ /var/tmp/diff_new_pack.QfuY8x/_new 2016-03-16 10:35:10.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package nemo # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -20,7 +20,7 @@ %define sover 1 %define typelib typelib-1_0-Nemo-3_0 Name: nemo -Version: 2.8.6 +Version: 2.8.7 Release: 0 Summary: File browser for Cinnamon License: GPL-2.0+ ++++++ nemo-2.8.6.tar.gz -> nemo-2.8.7.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/configure.ac new/nemo-2.8.7/configure.ac --- old/nemo-2.8.6/configure.ac 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/configure.ac 2016-03-07 18:19:50.000000000 +0100 @@ -18,7 +18,7 @@ m4_define(nemo_extension_current, 5) m4_define(nemo_extension_revision, 0) -AC_INIT(nemo, 2.8.6, https://github.com/linuxmint/nemo) +AC_INIT(nemo, 2.8.7, https://github.com/linuxmint/nemo) dnl =========================================================================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/data/icons/Makefile.am new/nemo-2.8.7/data/icons/Makefile.am --- old/nemo-2.8.6/data/icons/Makefile.am 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/data/icons/Makefile.am 2016-03-07 18:19:50.000000000 +0100 @@ -19,7 +19,9 @@ hicolor_actions_scalable_sidebar-tree-symbolic.svg \ hicolor_actions_scalable_sidebar-places-symbolic.svg \ hicolor_actions_scalable_expand-menu-symbolic.svg \ + hicolor_actions_scalable_expand-menu-hover-symbolic.svg \ hicolor_actions_scalable_collapse-menu-symbolic.svg \ + hicolor_actions_scalable_collapse-menu-hover-symbolic.svg \ hicolor_status_48x48_progress-0.png \ hicolor_status_48x48_progress-10.png \ hicolor_status_48x48_progress-20.png \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/data/icons/hicolor_actions_scalable_collapse-menu-hover-symbolic.svg new/nemo-2.8.7/data/icons/hicolor_actions_scalable_collapse-menu-hover-symbolic.svg --- old/nemo-2.8.6/data/icons/hicolor_actions_scalable_collapse-menu-hover-symbolic.svg 1970-01-01 01:00:00.000000000 +0100 +++ new/nemo-2.8.7/data/icons/hicolor_actions_scalable_collapse-menu-hover-symbolic.svg 2016-03-07 18:19:50.000000000 +0100 @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + id="svg7384" + height="16" + width="16" + version="1.1" + inkscape:version="0.91 r" + sodipodi:docname="hicolor_actions_scalable_collapse-menu-hover-symbolic.svg"> + <defs + id="defs9" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1003" + id="namedview7" + showgrid="false" + inkscape:zoom="14.75" + inkscape:cx="-15.050847" + inkscape:cy="8" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:window-maximized="1" + inkscape:current-layer="svg7384" /> + <metadata + id="metadata90"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title>Gnome Symbolic Icon Theme</dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <title + id="title9167">Gnome Symbolic Icon Theme</title> + <path + style="fill:#bebebe;fill-opacity:1" + d="M 9.5,1.5 A 6.5,6.5 0 0 0 3,8 6.5,6.5 0 0 0 9.5,14.5 6.5,6.5 0 0 0 16,8 6.5,6.5 0 0 0 9.5,1.5 Z M 6,7 13,7 13,9 6,9 6,7 Z" + id="path4223" + inkscape:connector-curvature="0" /> + <g + id="layer12" + transform="matrix(0.70002797,0,0,1,-25.601203,-726.0002)" /> +</svg> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/data/icons/hicolor_actions_scalable_collapse-menu-symbolic.svg new/nemo-2.8.7/data/icons/hicolor_actions_scalable_collapse-menu-symbolic.svg --- old/nemo-2.8.6/data/icons/hicolor_actions_scalable_collapse-menu-symbolic.svg 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/data/icons/hicolor_actions_scalable_collapse-menu-symbolic.svg 2016-03-07 18:19:50.000000000 +0100 @@ -31,7 +31,7 @@ id="namedview7" showgrid="false" inkscape:zoom="14.75" - inkscape:cx="-3.4237288" + inkscape:cx="-15.050847" inkscape:cy="8" inkscape:window-x="0" inkscape:window-y="25" @@ -53,7 +53,7 @@ id="title9167">Gnome Symbolic Icon Theme</title> <g id="layer12" - transform="matrix(0.70002797,0,0,1,-23.601203,-726)"> + transform="matrix(0.70002797,0,0,1,-24.101203,-726.0002)"> <rect id="rect31984" style="color:#bebebe;fill:#bebebe" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/data/icons/hicolor_actions_scalable_expand-menu-hover-symbolic.svg new/nemo-2.8.7/data/icons/hicolor_actions_scalable_expand-menu-hover-symbolic.svg --- old/nemo-2.8.6/data/icons/hicolor_actions_scalable_expand-menu-hover-symbolic.svg 1970-01-01 01:00:00.000000000 +0100 +++ new/nemo-2.8.7/data/icons/hicolor_actions_scalable_expand-menu-hover-symbolic.svg 2016-03-07 18:19:50.000000000 +0100 @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + id="svg7384" + height="16" + width="16" + version="1.1" + inkscape:version="0.91 r" + sodipodi:docname="hicolor_actions_scalable_expand-menu-hover-symbolic.svg"> + <defs + id="defs9" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1003" + id="namedview7" + showgrid="false" + inkscape:zoom="14.75" + inkscape:cx="-13.305229" + inkscape:cy="10.71689" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:window-maximized="1" + inkscape:current-layer="svg7384" /> + <metadata + id="metadata90"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title>Gnome Symbolic Icon Theme</dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <title + id="title9167">Gnome Symbolic Icon Theme</title> + <path + id="path4223" + style="fill:#bebebe;fill-opacity:1" + d="M 9.5,2.4999998 A 5.5,5.5 0 0 0 4,8 5.5,5.5 0 0 0 9.5,13.5 5.5,5.5 0 0 0 15,8 5.5,5.5 0 0 0 9.5,2.4999998 Z m -1,2 2,0 L 10.5,7 13,7 l 0,2 -2.5,0 0,2.5 -2,0 L 8.5,9 6,9 6,7 8.5,7 8.5,4.4999998 Z M 9.5,1.5 A 6.5,6.5 0 0 0 3,8 6.5,6.5 0 0 0 9.5,14.5 6.5,6.5 0 0 0 16,8 6.5,6.5 0 0 0 9.5,1.5 Z m 0,1.5 a 5,5 0 0 1 5,5 5,5 0 0 1 -5,5 5,5 0 0 1 -5,-5 5,5 0 0 1 5,-5 z" + inkscape:connector-curvature="0" /> + <g + id="layer12-7" + transform="matrix(0,-0.70002797,1,0,-726,41.601203)" /> +</svg> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/data/icons/hicolor_actions_scalable_expand-menu-symbolic.svg new/nemo-2.8.7/data/icons/hicolor_actions_scalable_expand-menu-symbolic.svg --- old/nemo-2.8.6/data/icons/hicolor_actions_scalable_expand-menu-symbolic.svg 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/data/icons/hicolor_actions_scalable_expand-menu-symbolic.svg 2016-03-07 18:19:50.000000000 +0100 @@ -31,8 +31,8 @@ id="namedview7" showgrid="false" inkscape:zoom="14.75" - inkscape:cx="-14.983051" - inkscape:cy="8" + inkscape:cx="-22.187982" + inkscape:cy="8.2033898" inkscape:window-x="0" inkscape:window-y="25" inkscape:window-maximized="1" @@ -53,7 +53,7 @@ id="title9167">Gnome Symbolic Icon Theme</title> <g id="layer12" - transform="matrix(0.70002797,0,0,1,-23.601203,-726)"> + transform="matrix(0.70002797,0,0,1,-24.101203,-726)"> <rect id="rect31984" style="color:#bebebe;fill:#bebebe" @@ -64,7 +64,7 @@ </g> <g id="layer12-7" - transform="matrix(0,-0.70002797,1,0,-724,41.601203)"> + transform="matrix(0,-0.70002797,1,0,-724.5,41.601203)"> <rect id="rect31984-6" style="color:#bebebe;fill:#bebebe" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/debian/changelog new/nemo-2.8.7/debian/changelog --- old/nemo-2.8.6/debian/changelog 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/debian/changelog 2016-03-07 18:19:50.000000000 +0100 @@ -1,3 +1,18 @@ +nemo (2.8.7) rosa; urgency=medium + + [ Michael Webster ] + * improve context menu toggle: - shows separate distinct regions of the menu item now - tooltip manifests as right-justified text next to the toggle icon + + [ monsta ] + * use g_strcmp0 instead of unsafe strcmp + + [ itzexor ] + * file: don't crash when the original file path has reserved characters https://git.gnome.org/browse/nautilus/commit/?id=d69885bd67edc1fae76c790f6162807817d63b2f + * file-operations: Make sure to use correct filename when restoring from Trash https://git.gnome.org/browse/nautilus/commit/libnautilus-private/nautilus-file-operations.c?id=ecee8be850b8342c804de2ecc3e613b99a20a010 + * file-utils: ensure directories exist before restoring from trash https://git.gnome.org/browse/nautilus/commit/?id=f1cb32831df32009f7e8bd5fcc35c5ccdf64eee4 + + -- Clement Lefebvre <[email protected]> Mon, 07 Mar 2016 17:19:06 +0000 + nemo (2.8.6) rosa; urgency=medium [ Michael Webster ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/libnemo-private/Makefile.am new/nemo-2.8.7/libnemo-private/Makefile.am --- old/nemo-2.8.6/libnemo-private/Makefile.am 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/libnemo-private/Makefile.am 2016-03-07 18:19:50.000000000 +0100 @@ -75,6 +75,8 @@ nemo-column-chooser.h \ nemo-column-utilities.c \ nemo-column-utilities.h \ + nemo-context-menu-menu-item.c \ + nemo-context-menu-menu-item.h \ nemo-dbus-manager.c \ nemo-dbus-manager.h \ nemo-debug.c \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/libnemo-private/nemo-context-menu-menu-item.c new/nemo-2.8.7/libnemo-private/nemo-context-menu-menu-item.c --- old/nemo-2.8.6/libnemo-private/nemo-context-menu-menu-item.c 1970-01-01 01:00:00.000000000 +0100 +++ new/nemo-2.8.7/libnemo-private/nemo-context-menu-menu-item.c 2016-03-07 18:19:50.000000000 +0100 @@ -0,0 +1,452 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ +#include <config.h> + +#include "nemo-global-preferences.h" +#include "nemo-context-menu-menu-item.h" +#include "nemo-widget-action.h" + +#include <glib/gi18n.h> + +static GtkActivatableIface *parent_activatable_iface; + +static void nemo_context_menu_menu_item_dispose (GObject *object); + +static gboolean nemo_context_menu_menu_item_enter (GtkWidget *widget, + GdkEventCrossing *event); +static gboolean nemo_context_menu_menu_item_leave (GtkWidget *widget, + GdkEventCrossing *event); +static gboolean nemo_context_menu_menu_item_motion (GtkWidget *widget, + GdkEventMotion *event); + +static gboolean nemo_context_menu_menu_item_button_press (GtkWidget *widget, + GdkEventButton *event); + +static gboolean nemo_context_menu_menu_item_button_release (GtkWidget *widget, + GdkEventButton *event); + +static void nemo_context_menu_menu_item_set_label (GtkMenuItem *menu_item, + const gchar *label); + +static void nemo_context_menu_menu_item_activatable_interface_init (GtkActivatableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (NemoContextMenuMenuItem, nemo_context_menu_menu_item, GTK_TYPE_IMAGE_MENU_ITEM, + G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE, + nemo_context_menu_menu_item_activatable_interface_init)); + +static void +set_action_image_temporary_visibility (NemoContextMenuMenuItem *item, + gboolean visible) +{ + GtkWidget *image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (item)); + + if (!visible) { + gtk_widget_set_visible (image, FALSE); + } else { + if (gtk_image_menu_item_get_always_show_image (GTK_IMAGE_MENU_ITEM (item))) { + gtk_widget_set_visible (image, TRUE); + } + } +} + +static void +update_toggle_state (NemoContextMenuMenuItem *item, + gboolean from_event, + gboolean on_item) +{ + gboolean complex_mode = g_settings_get_boolean (nemo_preferences, NEMO_PREFERENCES_CONTEXT_MENUS_SHOW_ALL_ACTIONS); + + /* const */ gchar *tip_text = complex_mode ? _("Show less actions") : + _("Show more actions"); + + gchar *markup = g_strdup_printf ("<small><i>%s</i></small>", tip_text); + + gtk_label_set_markup (GTK_LABEL (item->toggle_label_widget), markup); + + g_free (markup); + + if (item->on_toggle) { + set_action_image_temporary_visibility (item, FALSE); + gtk_stack_set_visible_child_name (GTK_STACK (item->stack), "toggle"); + } else { + set_action_image_temporary_visibility (item, TRUE); + gtk_stack_set_visible_child_name (GTK_STACK (item->stack), "action"); + } + + GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET (item)); + + if (on_item) { + gtk_image_set_from_icon_name (GTK_IMAGE (item->toggle_widget), + complex_mode ? "collapse-menu-hover-symbolic" : "expand-menu-hover-symbolic", + GTK_ICON_SIZE_MENU); + } else { + gtk_image_set_from_icon_name (GTK_IMAGE (item->toggle_widget), + complex_mode ? "collapse-menu-symbolic" : "expand-menu-symbolic", + GTK_ICON_SIZE_MENU); + } + + GtkStateFlags default_item_state = from_event ? GTK_STATE_FLAG_PRELIGHT : gtk_style_context_get_state (context); + + gtk_style_context_set_state (context, item->on_toggle ? GTK_STATE_FLAG_NORMAL : default_item_state); + + gtk_widget_queue_draw (GTK_WIDGET (item)); +} + +static void +update_toggle_appearance_from_event (GtkWidget *widget, + gint x, + gint y, + gboolean on_item) +{ + NemoContextMenuMenuItem *item = NEMO_CONTEXT_MENU_MENU_ITEM (widget); + GtkAllocation alloc; + + gtk_widget_get_allocation (item->toggle_widget, &alloc); + + item->on_toggle = ((x >= alloc.x) && + (x <= alloc.x + alloc.width) && + (y >= alloc.y) && + (y <= alloc.y + alloc.height)); + + update_toggle_state (item, TRUE, on_item); +} + +static void +nemo_context_menu_menu_item_class_init (NemoContextMenuMenuItemClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass*) klass; + GtkMenuItemClass *menu_item_class = (GtkMenuItemClass*) klass; + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + gobject_class->dispose = nemo_context_menu_menu_item_dispose; + + menu_item_class->set_label = nemo_context_menu_menu_item_set_label; + + widget_class->enter_notify_event = nemo_context_menu_menu_item_enter; + widget_class->leave_notify_event = nemo_context_menu_menu_item_leave; + widget_class->motion_notify_event = nemo_context_menu_menu_item_motion; + widget_class->button_press_event = nemo_context_menu_menu_item_button_press; + widget_class->button_release_event = nemo_context_menu_menu_item_button_release; +} + +static void +nemo_context_menu_menu_item_init (NemoContextMenuMenuItem *item) +{ + item->on_toggle = FALSE; + GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + + GtkWidget *stack = gtk_stack_new (); + + item->stack = stack; + + GtkWidget *label = gtk_label_new (NULL); + gtk_misc_set_alignment (GTK_MISC (label), 0.98, 0.5); + gtk_stack_add_named (GTK_STACK (stack), label, "toggle"); + item->toggle_label_widget = label; + + label = gtk_label_new (NULL); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_stack_add_named (GTK_STACK (stack), label, "action"); + item->label_widget = label; + + gtk_box_pack_start (GTK_BOX (box), stack, TRUE, TRUE, 0); + + GtkWidget *toggle = gtk_image_new (); + gtk_box_pack_end (GTK_BOX (box), toggle, FALSE, FALSE, 0); + item->toggle_widget = toggle; + + gtk_widget_show_all (box); + + gtk_container_add (GTK_CONTAINER (item), box); + + update_toggle_state (item, FALSE, FALSE); + + item->settings_monitor_id = g_signal_connect_swapped (nemo_preferences, + "changed::" NEMO_PREFERENCES_CONTEXT_MENUS_SHOW_ALL_ACTIONS, + G_CALLBACK (update_toggle_state), + item); +} + +static void +nemo_context_menu_menu_item_dispose (GObject *object) +{ + NemoContextMenuMenuItem *item = NEMO_CONTEXT_MENU_MENU_ITEM (object); + + if (item->settings_monitor_id > 0) { + g_signal_handler_disconnect (nemo_preferences, item->settings_monitor_id); + item->settings_monitor_id = 0; + } + + G_OBJECT_CLASS (nemo_context_menu_menu_item_parent_class)->dispose (object); +} + +static gboolean +nemo_context_menu_menu_item_enter (GtkWidget *widget, + GdkEventCrossing *event) +{ + g_return_val_if_fail (event != NULL, FALSE); + + update_toggle_appearance_from_event (widget, event->x, event->y, TRUE); + + return gtk_widget_event (gtk_widget_get_parent (widget), (GdkEvent *) event); +} + +static gboolean +nemo_context_menu_menu_item_leave (GtkWidget *widget, + GdkEventCrossing *event) +{ + g_return_val_if_fail (event != NULL, FALSE); + + update_toggle_appearance_from_event (widget, event->x, event->y, FALSE); + + return gtk_widget_event (gtk_widget_get_parent (widget), (GdkEvent *) event); +} + +static gboolean +nemo_context_menu_menu_item_motion (GtkWidget *widget, + GdkEventMotion *event) +{ + g_return_val_if_fail (event != NULL, FALSE); + + update_toggle_appearance_from_event (widget, event->x, event->y, TRUE); + + return gtk_widget_event (gtk_widget_get_parent (widget), (GdkEvent *) event); +} + +static gboolean +nemo_context_menu_menu_item_button_press (GtkWidget *widget, + GdkEventButton *event) +{ + NemoContextMenuMenuItem *item = NEMO_CONTEXT_MENU_MENU_ITEM (widget); + + if (event->button != GDK_BUTTON_PRIMARY) + return GDK_EVENT_PROPAGATE; + + update_toggle_appearance_from_event (widget, event->x, event->y, TRUE); + + if (item->on_toggle) { + g_settings_set_boolean (nemo_preferences, + NEMO_PREFERENCES_CONTEXT_MENUS_SHOW_ALL_ACTIONS, + !g_settings_get_boolean (nemo_preferences, + NEMO_PREFERENCES_CONTEXT_MENUS_SHOW_ALL_ACTIONS)); + return GDK_EVENT_STOP; + } + + return GDK_EVENT_PROPAGATE; +} + +static gboolean +nemo_context_menu_menu_item_button_release (GtkWidget *widget, + GdkEventButton *event) +{ + NemoContextMenuMenuItem *item = NEMO_CONTEXT_MENU_MENU_ITEM (widget); + + if (event->button != GDK_BUTTON_PRIMARY && + event->button != GDK_BUTTON_SECONDARY) + return GDK_EVENT_PROPAGATE; + + update_toggle_appearance_from_event (widget, event->x, event->y, TRUE); + + if (item->on_toggle) { + return GDK_EVENT_STOP; + } + + return GDK_EVENT_PROPAGATE; +} + +static void +nemo_context_menu_menu_item_set_label (GtkMenuItem *menu_item, + const gchar *label) +{ + NemoContextMenuMenuItem *item = NEMO_CONTEXT_MENU_MENU_ITEM (menu_item); + + if (item->label != label) + { + g_free (item->label); + item->label = g_strdup (label); + + gtk_label_set_text_with_mnemonic (GTK_LABEL (item->label_widget), label); + + g_object_notify (G_OBJECT (menu_item), "label"); + } +} + +static gboolean +activatable_update_stock_id (GtkImageMenuItem *image_menu_item, + GtkAction *action) +{ + GtkWidget *image; + const gchar *stock_id = gtk_action_get_stock_id (action); + + image = gtk_image_menu_item_get_image (image_menu_item); + + if (GTK_IS_IMAGE (image) && + stock_id && gtk_icon_factory_lookup_default (stock_id)) { + gtk_image_set_from_stock (GTK_IMAGE (image), stock_id, GTK_ICON_SIZE_MENU); + return TRUE; + } + + return FALSE; +} + +static gboolean +activatable_update_gicon (GtkImageMenuItem *image_menu_item, + GtkAction *action) +{ + GtkWidget *image; + GIcon *icon = gtk_action_get_gicon (action); + const gchar *stock_id; + gboolean ret = FALSE; + + stock_id = gtk_action_get_stock_id (action); + + image = gtk_image_menu_item_get_image (image_menu_item); + + if (icon && GTK_IS_IMAGE (image) && + !(stock_id && gtk_icon_factory_lookup_default (stock_id))) { + gtk_image_set_from_gicon (GTK_IMAGE (image), icon, GTK_ICON_SIZE_MENU); + ret = TRUE; + } + + return ret; +} + +static void +activatable_update_icon_name (GtkImageMenuItem *image_menu_item, + GtkAction *action) +{ + GtkWidget *image; + const gchar *icon_name = gtk_action_get_icon_name (action); + + image = gtk_image_menu_item_get_image (image_menu_item); + + if (GTK_IS_IMAGE (image) && + (gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY || + gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_ICON_NAME)) { + gtk_image_set_from_icon_name (GTK_IMAGE (image), icon_name, GTK_ICON_SIZE_MENU); + } +} + +static void +activatable_update_label (GtkMenuItem *menu_item, GtkAction *action) +{ + const gchar *label; + label = gtk_action_get_label (action); + nemo_context_menu_menu_item_set_label (menu_item, label); +} + +static void +nemo_context_menu_menu_item_update (GtkActivatable *activatable, + GtkAction *action, + const gchar *property_name) +{ + if (!gtk_activatable_get_use_action_appearance (activatable)) + return; + if (strcmp (property_name, "label") == 0) + activatable_update_label (GTK_MENU_ITEM (activatable), action); + else if (strcmp (property_name, "stock-id") == 0) + activatable_update_stock_id (GTK_IMAGE_MENU_ITEM (activatable), action); + else if (strcmp (property_name, "gicon") == 0) + activatable_update_gicon (GTK_IMAGE_MENU_ITEM (activatable), action); + else if (strcmp (property_name, "icon-name") == 0) + activatable_update_icon_name (GTK_IMAGE_MENU_ITEM (activatable), action); +} + +static void +menu_item_sync_action_properties (NemoContextMenuMenuItem *menu_item, + GtkAction *action) +{ + GtkImageMenuItem *image_menu_item; + GtkActivatable *activatable; + GtkWidget *image; + gboolean use_appearance; + + image_menu_item = GTK_IMAGE_MENU_ITEM (menu_item); + + activatable = GTK_ACTIVATABLE (image_menu_item); + + if (!action) + return; + + use_appearance = gtk_activatable_get_use_action_appearance (activatable); + if (!use_appearance) + return; + + image = gtk_image_menu_item_get_image (image_menu_item); + if (image && !GTK_IS_IMAGE (image)) { + gtk_image_menu_item_set_image (image_menu_item, NULL); + image = NULL; + } + + if (!image) { + image = gtk_image_new (); + gtk_widget_show (image); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (activatable), + image); + } + + if (!activatable_update_stock_id (image_menu_item, action) && + !activatable_update_gicon (image_menu_item, action)) + activatable_update_icon_name (image_menu_item, action); + + gtk_image_menu_item_set_always_show_image (image_menu_item, + gtk_action_get_always_show_image (action)); + + activatable_update_label (GTK_MENU_ITEM (menu_item), action); +} + +static void +nemo_context_menu_menu_item_sync_action_properties (GtkActivatable *activatable, + GtkAction *action) +{ + NemoContextMenuMenuItem *context_menu_menu_item; + + context_menu_menu_item = NEMO_CONTEXT_MENU_MENU_ITEM (activatable); + + if (!action) + return; + + if (!gtk_activatable_get_use_action_appearance (activatable)) + return; + + menu_item_sync_action_properties (context_menu_menu_item, action); + + gtk_widget_show (GTK_WIDGET (context_menu_menu_item)); +} + +static void +nemo_context_menu_menu_item_activatable_interface_init (GtkActivatableIface *iface) +{ + parent_activatable_iface = g_type_interface_peek_parent (iface); + iface->update = nemo_context_menu_menu_item_update; + iface->sync_action_properties = nemo_context_menu_menu_item_sync_action_properties; +} + +/** + * nemo_context_menu_menu_item_new: + * @widget: The custom widget to use + * + * Creates a new #NemoContextMenuMenuItem. + * + * Returns: a new #NemoContextMenuMenuItem. + */ +GtkWidget * +nemo_context_menu_menu_item_new (GtkWidget *widget) +{ + return g_object_new (NEMO_TYPE_CONTEXT_MENU_MENU_ITEM, + NULL); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/libnemo-private/nemo-context-menu-menu-item.h new/nemo-2.8.7/libnemo-private/nemo-context-menu-menu-item.h --- old/nemo-2.8.6/libnemo-private/nemo-context-menu-menu-item.h 1970-01-01 01:00:00.000000000 +0100 +++ new/nemo-2.8.7/libnemo-private/nemo-context-menu-menu-item.h 2016-03-07 18:19:50.000000000 +0100 @@ -0,0 +1,71 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __NEMO_CONTEXT_MENU_MENU_ITEM_H__ +#define __NEMO_CONTEXT_MENU_MENU_ITEM_H__ + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define NEMO_TYPE_CONTEXT_MENU_MENU_ITEM (nemo_context_menu_menu_item_get_type ()) +#define NEMO_CONTEXT_MENU_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NEMO_TYPE_CONTEXT_MENU_MENU_ITEM, NemoContextMenuMenuItem)) +#define NEMO_CONTEXT_MENU_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NEMO_TYPE_CONTEXT_MENU_MENU_ITEM, NemoContextMenuMenuItemClass)) +#define NEMO_IS_CONTEXT_MENU_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NEMO_TYPE_CONTEXT_MENU_MENU_ITEM)) +#define NEMO_IS_CONTEXT_MENU_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NEMO_TYPE_CONTEXT_MENU_MENU_ITEM)) +#define NEMO_CONTEXT_MENU_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NEMO_TYPE_CONTEXT_MENU_MENU_ITEM, NemoContextMenuMenuItemClass)) + + +typedef struct _NemoContextMenuMenuItem NemoContextMenuMenuItem; +typedef struct _NemoContextMenuMenuItemClass NemoContextMenuMenuItemClass; + +struct _NemoContextMenuMenuItem +{ + GtkImageMenuItem menu_item; + + gchar *label; + GtkWidget *stack; + GtkWidget *label_widget; + GtkWidget *toggle_label_widget; + GtkWidget *toggle_widget; + + gulong settings_monitor_id; + gboolean on_toggle; +}; + +/** + * NemoContextMenuMenuItemClass: + * @parent_class: The parent class. + */ +struct _NemoContextMenuMenuItemClass +{ + GtkImageMenuItemClass parent_class; +}; + +GType nemo_context_menu_menu_item_get_type (void) G_GNUC_CONST; +GtkWidget *nemo_context_menu_menu_item_new (GtkWidget *widget); + +G_END_DECLS + +#endif /* __NEMO_CONTEXT_MENU_MENU_ITEM_H__ */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/libnemo-private/nemo-file-operations.c new/nemo-2.8.7/libnemo-private/nemo-file-operations.c --- old/nemo-2.8.6/libnemo-private/nemo-file-operations.c 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/libnemo-private/nemo-file-operations.c 2016-03-07 18:19:50.000000000 +0100 @@ -3382,18 +3382,28 @@ if (dest == NULL && !same_fs) { info = g_file_query_info (src, - G_FILE_ATTRIBUTE_STANDARD_COPY_NAME, + G_FILE_ATTRIBUTE_STANDARD_COPY_NAME "," + G_FILE_ATTRIBUTE_TRASH_ORIG_PATH, 0, NULL, NULL); if (info) { - copyname = g_strdup (g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME)); + copyname = NULL; + + /* if file is being restored from trash make sure it uses its original name */ + if (g_file_has_uri_scheme (src, "trash")) { + copyname = g_strdup (g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_TRASH_ORIG_PATH)); + } + + if (copyname == NULL) { + copyname = g_strdup (g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME)); + } if (copyname) { make_file_name_valid_for_dest_fs (copyname, dest_fs_type); dest = g_file_get_child_for_display_name (dest_dir, copyname, NULL); g_free (copyname); } - + g_object_unref (info); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/libnemo-private/nemo-file-utilities.c new/nemo-2.8.7/libnemo-private/nemo-file-utilities.c --- old/nemo-2.8.6/libnemo-private/nemo-file-utilities.c 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/libnemo-private/nemo-file-utilities.c 2016-03-07 18:19:50.000000000 +0100 @@ -1248,15 +1248,92 @@ return g_list_reverse (ret); } +typedef struct { + GHashTable *original_dirs_hash; + GtkWindow *parent_window; +} RestoreFilesData; + +static void +ensure_dirs_task_ready_cb (GObject *_source, + GAsyncResult *res, + gpointer user_data) +{ + NemoFile *original_dir; + GFile *original_dir_location; + GList *original_dirs, *files, *locations, *l; + RestoreFilesData *data = user_data; + + original_dirs = g_hash_table_get_keys (data->original_dirs_hash); + for (l = original_dirs; l != NULL; l = l->next) { + original_dir = NEMO_FILE (l->data); + original_dir_location = nemo_file_get_location (original_dir); + + files = g_hash_table_lookup (data->original_dirs_hash, original_dir); + locations = locations_from_file_list (files); + + nemo_file_operations_move + (locations, NULL, + original_dir_location, + data->parent_window, + NULL, NULL); + + g_list_free_full (locations, g_object_unref); + g_object_unref (original_dir_location); + } + + g_list_free (original_dirs); + + g_hash_table_unref (data->original_dirs_hash); + g_slice_free (RestoreFilesData, data); +} + +static void +ensure_dirs_task_thread_func (GTask *task, + gpointer source, + gpointer task_data, + GCancellable *cancellable) +{ + RestoreFilesData *data = task_data; + NemoFile *original_dir; + GFile *original_dir_location; + GList *original_dirs, *l; + + original_dirs = g_hash_table_get_keys (data->original_dirs_hash); + for (l = original_dirs; l != NULL; l = l->next) { + original_dir = NEMO_FILE (l->data); + original_dir_location = nemo_file_get_location (original_dir); + + g_file_make_directory_with_parents (original_dir_location, cancellable, NULL); + g_object_unref (original_dir_location); + } + + g_task_return_pointer (task, NULL, NULL); +} + +static void +restore_files_ensure_parent_directories (GHashTable *original_dirs_hash, + GtkWindow *parent_window) +{ + RestoreFilesData *data; + GTask *ensure_dirs_task; + + data = g_slice_new0 (RestoreFilesData); + data->parent_window = parent_window; + data->original_dirs_hash = g_hash_table_ref (original_dirs_hash); + + ensure_dirs_task = g_task_new (NULL, NULL, ensure_dirs_task_ready_cb, data); + g_task_set_task_data (ensure_dirs_task, data, NULL); + g_task_run_in_thread (ensure_dirs_task, ensure_dirs_task_thread_func); + g_object_unref (ensure_dirs_task); +} + void nemo_restore_files_from_trash (GList *files, GtkWindow *parent_window) { - NemoFile *file, *original_dir; + NemoFile *file; GHashTable *original_dirs_hash; - GList *original_dirs, *unhandled_files; - GFile *original_dir_location; - GList *locations, *l; + GList *unhandled_files, *l; char *message, *file_name; original_dirs_hash = nemo_trashed_files_get_original_directories (files, &unhandled_files); @@ -1274,26 +1351,8 @@ } if (original_dirs_hash != NULL) { - original_dirs = g_hash_table_get_keys (original_dirs_hash); - for (l = original_dirs; l != NULL; l = l->next) { - original_dir = NEMO_FILE (l->data); - original_dir_location = nemo_file_get_location (original_dir); - - files = g_hash_table_lookup (original_dirs_hash, original_dir); - locations = locations_from_file_list (files); - - nemo_file_operations_move - (locations, NULL, - original_dir_location, - parent_window, - NULL, NULL); - - g_list_free_full (locations, g_object_unref); - g_object_unref (original_dir_location); - } - - g_list_free (original_dirs); - g_hash_table_destroy (original_dirs_hash); + restore_files_ensure_parent_directories (original_dirs_hash, parent_window); + g_hash_table_unref (original_dirs_hash); } nemo_file_list_unref (unhandled_files); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/libnemo-private/nemo-file.c new/nemo-2.8.7/libnemo-private/nemo-file.c --- old/nemo-2.8.6/libnemo-private/nemo-file.c 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/libnemo-private/nemo-file.c 2016-03-07 18:19:50.000000000 +0100 @@ -7297,17 +7297,13 @@ { GFile *location; NemoFile *original_file; - char *filename; original_file = NULL; if (file->details->trash_orig_path != NULL) { - /* file name is stored in URL encoding */ - filename = g_uri_unescape_string (file->details->trash_orig_path, ""); - location = g_file_new_for_path (filename); + location = g_file_new_for_path (file->details->trash_orig_path); original_file = nemo_file_get (location); - g_object_unref (G_OBJECT (location)); - g_free (filename); + g_object_unref (location); } return original_file; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/libnemo-private/nemo-widget-action.c new/nemo-2.8.7/libnemo-private/nemo-widget-action.c --- old/nemo-2.8.6/libnemo-private/nemo-widget-action.c 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/libnemo-private/nemo-widget-action.c 2016-03-07 18:19:50.000000000 +0100 @@ -19,6 +19,7 @@ #include "nemo-widget-action.h" #include "nemo-widget-menu-item.h" +#include "nemo-context-menu-menu-item.h" G_DEFINE_TYPE (NemoWidgetAction, nemo_widget_action, GTK_TYPE_ACTION); @@ -62,6 +63,7 @@ action->widget_b = NULL; action->a_used = FALSE; action->b_used = FALSE; + action->is_menu_toggle = FALSE; } static void @@ -118,6 +120,22 @@ NULL); } +GtkAction * +nemo_widget_action_new_for_menu_toggle (const gchar *name, + const gchar *label, + const gchar *tooltip) +{ + GtkAction *ret = g_object_new (NEMO_TYPE_WIDGET_ACTION, + "name", name, + "label", label, + "tooltip", tooltip, + NULL); + + NEMO_WIDGET_ACTION (ret)->is_menu_toggle = TRUE; + + return ret; +} + static void nemo_widget_action_finalize (GObject *object) { @@ -198,29 +216,35 @@ { NemoWidgetAction *widget_action; GType menu_item_type; - GtkWidget *w, *ret; - gint slot; + GtkWidget *w; + GtkWidget *ret = NULL; + gint slot = -1; widget_action = NEMO_WIDGET_ACTION (action); menu_item_type = GTK_ACTION_GET_CLASS (action)->menu_item_type; - if (!widget_action->a_used) { - w = widget_action->widget_a; - widget_action->a_used = TRUE; - slot = ACTION_SLOT_A; - } else if (!widget_action->b_used) { - w = widget_action->widget_b; - widget_action->b_used = TRUE; - slot = ACTION_SLOT_B; - } else - return NULL; - - ret = g_object_new (menu_item_type, - "child-widget", w, - "action-slot", slot, - NULL); + if (widget_action->is_menu_toggle) { + ret = g_object_new (NEMO_TYPE_CONTEXT_MENU_MENU_ITEM, NULL); + } else { + if (!widget_action->a_used) { + w = widget_action->widget_a; + widget_action->a_used = TRUE; + slot = ACTION_SLOT_A; + } else if (!widget_action->b_used) { + w = widget_action->widget_b; + widget_action->b_used = TRUE; + slot = ACTION_SLOT_B; + } + + if (slot != -1) + ret = g_object_new (menu_item_type, + "child-widget", w, + "action-slot", slot, + NULL); + } - gtk_activatable_set_related_action (GTK_ACTIVATABLE (ret), action); + if (ret) + gtk_activatable_set_related_action (GTK_ACTIVATABLE (ret), action); return ret; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/libnemo-private/nemo-widget-action.h new/nemo-2.8.7/libnemo-private/nemo-widget-action.h --- old/nemo-2.8.6/libnemo-private/nemo-widget-action.h 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/libnemo-private/nemo-widget-action.h 2016-03-07 18:19:50.000000000 +0100 @@ -44,6 +44,7 @@ GtkWidget *widget_b; gboolean a_used; gboolean b_used; + gboolean is_menu_toggle; }; struct _NemoWidgetActionClass { @@ -59,6 +60,10 @@ GtkAction *nemo_widget_action_new (const gchar *name, GtkWidget *widget_a, GtkWidget *widget_b); +GtkAction *nemo_widget_action_new_for_menu_toggle (const gchar *name, + const gchar *label, + const gchar *tooltip); + void nemo_widget_action_activate (NemoWidgetAction *action); GtkWidget * nemo_widget_action_get_widget_a (NemoWidgetAction *action); void nemo_widget_action_set_widget_a (NemoWidgetAction *action, GtkWidget *widget); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/src/nemo-actions.h new/nemo-2.8.7/src/nemo-actions.h --- old/nemo-2.8.6/src/nemo-actions.h 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/src/nemo-actions.h 2016-03-07 18:19:50.000000000 +0100 @@ -60,6 +60,7 @@ #define NEMO_ACTION_NEW_TAB "New Tab" #define NEMO_ACTION_OPEN "Open" +#define NEMO_ACTION_OPEN_TOGGLE "OpenToggle" #define NEMO_ACTION_OPEN_ALTERNATE "OpenAlternate" #define NEMO_ACTION_OPEN_IN_NEW_TAB "OpenInNewTab" #define NEMO_ACTION_LOCATION_OPEN_ALTERNATE "LocationOpenAlternate" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/src/nemo-directory-view-ui.xml new/nemo-2.8.7/src/nemo-directory-view-ui.xml --- old/nemo-2.8.6/src/nemo-directory-view-ui.xml 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/src/nemo-directory-view-ui.xml 2016-03-07 18:19:50.000000000 +0100 @@ -147,7 +147,7 @@ </popup> <popup name="selection"> <placeholder name="Open Placeholder"> - <menuitem name="Open" action="Open"/> + <menuitem name="OpenToggle" action="OpenToggle"/> <menuitem name="OpenInNewTab" action="OpenInNewTab"/> <menuitem name="OpenAlternate" action="OpenAlternate"/> <separator name="applications separator"/> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/src/nemo-icon-view.c new/nemo-2.8.7/src/nemo-icon-view.c --- old/nemo-2.8.6/src/nemo-icon-view.c 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/src/nemo-icon-view.c 2016-03-07 18:19:50.000000000 +0100 @@ -932,7 +932,7 @@ /* Figure out what the new sort setting should be. */ for (i = 0; i < G_N_ELEMENTS (sort_criteria); i++) { - if (strcmp (sort_criteria[i].metadata_text, metadata_text) == 0) { + if (g_strcmp0 (sort_criteria[i].metadata_text, metadata_text) == 0) { return &sort_criteria[i]; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nemo-2.8.6/src/nemo-view.c new/nemo-2.8.7/src/nemo-view.c --- old/nemo-2.8.6/src/nemo-view.c 2015-11-27 11:00:22.000000000 +0100 +++ new/nemo-2.8.7/src/nemo-view.c 2016-03-07 18:19:50.000000000 +0100 @@ -127,7 +127,7 @@ #define NEMO_VIEW_POPUP_PATH_SCRIPTS_PLACEHOLDER "/selection/Open Placeholder/Scripts/Scripts Placeholder" #define NEMO_VIEW_POPUP_PATH_ACTIONS_PLACEHOLDER "/selection/Open Placeholder/ActionsPlaceholder" #define NEMO_VIEW_POPUP_PATH_EXTENSION_ACTIONS "/selection/Extension Actions" -#define NEMO_VIEW_POPUP_PATH_OPEN "/selection/Open Placeholder/Open" +#define NEMO_VIEW_POPUP_PATH_OPEN "/selection/Open Placeholder/OpenToggle" #define NEMO_VIEW_POPUP_PATH_BACKGROUND "/background" #define NEMO_VIEW_POPUP_PATH_BACKGROUND_SCRIPTS_PLACEHOLDER "/background/Before Zoom Items/New Object Items/Scripts/Scripts Placeholder" @@ -193,12 +193,6 @@ GtkActionGroup *dir_action_group; guint dir_merge_id; - GtkWidget *expander_menu_widget; - GtkWidget *menu_widget_ref; - GtkWidget *expander_label_widget; - guint menu_expander_click_handler_id; - gchar *expander_tooltip_text; - gboolean supports_zooming; GList *scripts_directory_list; @@ -2686,12 +2680,6 @@ /* Default to true; desktop-icon-view sets to false */ view->details->show_foreign_files = TRUE; - view->details->expander_menu_widget = NULL; - view->details->menu_widget_ref = NULL; - view->details->expander_label_widget = NULL; - view->details->menu_expander_click_handler_id = 0; - view->details->expander_tooltip_text = NULL; - view->details->non_ready_files = g_hash_table_new_full (file_and_directory_hash, file_and_directory_equal, @@ -2779,6 +2767,10 @@ nemo_to_menu_preferences_changed_callback (view); + g_signal_connect_swapped (nemo_preferences, + "changed::" NEMO_PREFERENCES_CONTEXT_MENUS_SHOW_ALL_ACTIONS, + G_CALLBACK (schedule_update_menus), view); + manager = nemo_file_undo_manager_get (); g_signal_connect_object (manager, "undo-changed", G_CALLBACK (undo_manager_changed_cb), view, 0); @@ -2871,15 +2863,6 @@ view = NEMO_VIEW (object); - if (view->details->expander_menu_widget != NULL) { - gtk_widget_destroy (view->details->expander_menu_widget); - } - - if (view->details->menu_expander_click_handler_id > 0) { - g_signal_handler_disconnect (view->details->menu_widget_ref, view->details->menu_expander_click_handler_id); - view->details->menu_expander_click_handler_id = 0; - } - disconnect_model_handlers (view); if (view->details->bookmarks_changed_id != 0) { @@ -2975,6 +2958,9 @@ g_signal_handlers_disconnect_by_func (nemo_preferences, nemo_to_menu_preferences_changed_callback, view); + g_signal_handlers_disconnect_by_func (nemo_preferences, + schedule_update_menus, view); + unschedule_pop_up_location_context_menu (view); if (view->details->location_popup_event != NULL) { gdk_event_free ((GdkEvent *) view->details->location_popup_event); @@ -6639,163 +6625,6 @@ g_free (templates_directory_uri); } -static void ensure_expander_attached (NemoView *view, GtkWidget *menu_item); - -static void -on_expander_destroyed (GtkWidget *widget, NemoView *view) -{ - view->details->expander_menu_widget = NULL; -} - -static void -on_menu_destroyed (GtkWidget *widget, NemoView *view) -{ - view->details->menu_widget_ref = NULL; - view->details->expander_label_widget = NULL; -} - -static gboolean -pointer_in_expander_widget (GtkWidget *widget, gint x, gint y) -{ - GtkAllocation alloc; - - gtk_widget_get_allocation (widget, &alloc); - - return ((x >= alloc.x) && - (x <= alloc.x + alloc.width) && - (y >= alloc.y) && - (y <= alloc.y + alloc.height)); -} - -static gboolean -on_query_menu_tooltip (GtkWidget *widget, - gint x, - gint y, - gboolean keyboard_mode, - GtkTooltip *tooltip, - gpointer user_data) -{ - NemoView *view = NEMO_VIEW (user_data); - - if (view->details->expander_menu_widget != NULL && - pointer_in_expander_widget (view->details->expander_menu_widget, x, y)) { - gtk_tooltip_set_text (tooltip, view->details->expander_tooltip_text); - return TRUE; - } - - gtk_tooltip_set_text (tooltip, NULL); - return FALSE; -} - -static GtkWidget * -get_expander_widget_and_tooltip (NemoView *view, gchar **tooltip) -{ - if (view->details->expander_menu_widget != NULL) - gtk_widget_destroy (view->details->expander_menu_widget); - - gboolean complex_mode = g_settings_get_boolean (nemo_preferences, - NEMO_PREFERENCES_CONTEXT_MENUS_SHOW_ALL_ACTIONS); - - GtkWidget *widget = gtk_image_new_from_icon_name (complex_mode ? "collapse-menu-symbolic" : "expand-menu-symbolic", - GTK_ICON_SIZE_MENU); - - *tooltip = complex_mode ? _("Show less actions") : _("Show more actions"); - - g_signal_connect (widget, "destroy", G_CALLBACK (on_expander_destroyed), view); - - return widget; -} - -static void -attach_expander (NemoView *view, GtkWidget *widget, GtkWidget *expander) -{ - GtkWidget *parent = gtk_widget_get_parent (widget); - GtkWidget *hbox = NULL; - - if (!GTK_IS_LABEL (widget) && !GTK_IS_BOX (widget)) - return; - - if (GTK_IS_LABEL (widget)) { - g_object_ref (widget); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - - gtk_container_remove (GTK_CONTAINER (parent), widget); - gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); - gtk_container_add (GTK_CONTAINER (parent), hbox); - - view->details->expander_label_widget = widget; - - g_object_unref (widget); - } - - if (GTK_IS_BOX (widget)) { - hbox = widget; - } - - gtk_box_pack_end (GTK_BOX (hbox), expander, FALSE, FALSE, 0); -} - -static gboolean -on_menu_button_released (GtkWidget *widget, GdkEvent *event, NemoView *view) -{ - if (event->button.button != GDK_BUTTON_PRIMARY) - return FALSE; - - gint ev_x = (gint) event->button.x; - gint ev_y = (gint) event->button.y; - - if (pointer_in_expander_widget (view->details->expander_menu_widget, ev_x, ev_y)) { - g_settings_set_boolean (nemo_preferences, - NEMO_PREFERENCES_CONTEXT_MENUS_SHOW_ALL_ACTIONS, - !g_settings_get_boolean (nemo_preferences, - NEMO_PREFERENCES_CONTEXT_MENUS_SHOW_ALL_ACTIONS)); - ensure_expander_attached (view, widget); - schedule_update_menus (view); - return TRUE; - } - - return FALSE; -} - -static void -ensure_expander_attached (NemoView *view, GtkWidget *menu_item) -{ - gchar *tooltip = NULL; - - GtkWidget *expander = get_expander_widget_and_tooltip (view, &tooltip); - - view->details->expander_menu_widget = expander; - - g_clear_pointer (&view->details->expander_tooltip_text, g_free); - view->details->expander_tooltip_text = g_strdup (tooltip); - - GtkWidget *child = gtk_bin_get_child (GTK_BIN (menu_item)); - - attach_expander (view, child, expander); - - gtk_widget_show_all (menu_item); - - if (view->details->menu_expander_click_handler_id == 0) { - view->details->menu_expander_click_handler_id = g_signal_connect (menu_item, - "button-release-event", - G_CALLBACK (on_menu_button_released), - view); - } - - if (view->details->menu_widget_ref == NULL) { - view->details->menu_widget_ref = menu_item; - g_signal_connect (menu_item, "destroy", G_CALLBACK (on_menu_destroyed), view); - } - - gtk_widget_set_has_tooltip (menu_item, TRUE); - - g_signal_handlers_disconnect_matched (menu_item, G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, on_query_menu_tooltip, NULL); - - g_signal_connect (menu_item, "query-tooltip", G_CALLBACK (on_query_menu_tooltip), view); -} - static GtkMenu * create_popup_menu (NemoView *view, const char *popup_path) { @@ -8268,7 +8097,7 @@ /* name, stock id */ { "Open", NULL, /* label, accelerator */ N_("_Open"), "<control>o", /* tooltip */ N_("Open the selected item in this window"), - G_CALLBACK (action_open_callback) }, + G_CALLBACK (action_open_callback) }, /* name, stock id */ { "OpenAccel", NULL, /* label, accelerator */ "OpenAccel", "<alt>Down", /* tooltip */ NULL, @@ -8603,6 +8432,17 @@ } } +static GtkAction * +get_expander_action (NemoView *view) +{ + GtkAction *action = nemo_widget_action_new_for_menu_toggle ("OpenToggle", N_("_Open"), + N_("Open the selected item in this window")); + + g_signal_connect (action, "activate", G_CALLBACK (action_open_callback), view); + + return action; +} + static void real_merge_menus (NemoView *view) { @@ -8620,6 +8460,9 @@ directory_view_entries, G_N_ELEMENTS (directory_view_entries), view); + /* Add the special Open action with built-in menu toggle*/ + gtk_action_group_add_action (action_group, get_expander_action (view)); + tooltip = g_strdup_printf (_("Run scripts")); /* Create a script action here specially because its tooltip is dynamic */ action = gtk_action_new ("Scripts", _("_Scripts"), tooltip, NULL); @@ -9630,6 +9473,7 @@ static void real_update_menus (NemoView *view) { + GtkWidget *menuitem; GList *selection, *l; gint selection_count; const char *tip, *label; @@ -9656,7 +9500,7 @@ GtkAction *action; GAppInfo *app; GIcon *app_icon; - GtkWidget *menuitem; + // GtkWidget *menuitem; gboolean next_pane_is_writable; gboolean show_properties; @@ -9711,10 +9555,6 @@ gtk_action_set_sensitive (action, can_create_files); gtk_action_set_visible (action, !selection_contains_recent); - action = gtk_action_group_get_action (view->details->dir_action_group, - NEMO_ACTION_OPEN); - gtk_action_set_sensitive (action, selection_count != 0); - can_open = show_app = selection_count != 0; for (l = selection; l != NULL; l = l->next) { @@ -9756,43 +9596,50 @@ g_object_unref (app); } - g_object_set (action, "label", - label_with_underscore ? label_with_underscore : _("_Open"), - NULL); - - if (view->details->expander_label_widget) { - gtk_label_set_text_with_mnemonic (GTK_LABEL (view->details->expander_label_widget), - label_with_underscore ? label_with_underscore : _("_Open")); - } - - menuitem = gtk_ui_manager_get_widget ( - nemo_window_get_ui_manager (view->details->window), - NEMO_VIEW_MENU_PATH_OPEN); - - /* Only force displaying the icon if it is an application icon */ - gtk_image_menu_item_set_always_show_image ( - GTK_IMAGE_MENU_ITEM (menuitem), app_icon != NULL); - - menuitem = gtk_ui_manager_get_widget ( - nemo_window_get_ui_manager (view->details->window), - NEMO_VIEW_POPUP_PATH_OPEN); - - ensure_expander_attached (view, menuitem); - - /* Only force displaying the icon if it is an application icon */ - gtk_image_menu_item_set_always_show_image ( - GTK_IMAGE_MENU_ITEM (menuitem), app_icon != NULL); - if (app_icon == NULL) { app_icon = g_themed_icon_new (GTK_STOCK_OPEN); } - gtk_action_set_gicon (action, app_icon); - g_object_unref (app_icon); + action = gtk_action_group_get_action (view->details->dir_action_group, + NEMO_ACTION_OPEN); + gtk_action_set_sensitive (action, selection_count != 0); - gtk_action_set_visible (action, can_open); - - g_free (label_with_underscore); + g_object_set (action, "label", + label_with_underscore ? label_with_underscore : _("_Open"), + NULL); + + gtk_action_set_gicon (action, app_icon); + gtk_action_set_visible (action, can_open); + + action = gtk_action_group_get_action (view->details->dir_action_group, + NEMO_ACTION_OPEN_TOGGLE); + gtk_action_set_sensitive (action, selection_count != 0); + + g_object_set (action, "label", + label_with_underscore ? label_with_underscore : _("_Open"), + NULL); + + gtk_action_set_gicon (action, app_icon); + gtk_action_set_visible (action, can_open); + + g_object_unref (app_icon); + g_free (label_with_underscore); + + menuitem = gtk_ui_manager_get_widget ( + nemo_window_get_ui_manager (view->details->window), + NEMO_VIEW_MENU_PATH_OPEN); + + /* Only force displaying the icon if it is an application icon */ + gtk_image_menu_item_set_always_show_image ( + GTK_IMAGE_MENU_ITEM (menuitem), app_icon != NULL); + + menuitem = gtk_ui_manager_get_widget ( + nemo_window_get_ui_manager (view->details->window), + NEMO_VIEW_POPUP_PATH_OPEN); + + /* Only force displaying the icon if it is an application icon */ + gtk_image_menu_item_set_always_show_image ( + GTK_IMAGE_MENU_ITEM (menuitem), app_icon != NULL); show_open_alternate = file_list_all_are_folders (selection) && selection_count > 0 &&
