[Pkg-ROX-devel] Bug#380664: rox-filer: pinboard click commands

Darren Salt linux at youmustbejoking.demon.co.uk
Mon Jul 31 18:04:37 UTC 2006


Package: rox-filer
Version: 2.4-1
Severity: wishlist
Forwarded: http://sourceforge.net/tracker/index.php?func=detail&aid=1531890&group_id=7023&atid=307023

Pinboard click commands are useful in situations when enabling the
forward-to-WM option isn't practical due to the WM not doing anything useful
with the information. Here, I'm using it to have right-click open the XFCE
menu via a lightly-hacked xfce4-menu-popup (since I happen to prefer
ROX-Filer over Thunar).

It may be worth tweaking the patch to provide a sensible default command to
launch a standalone popup menu program; if so, rox-filer should at least
recommend that package.

(The patch is tested with rox-filer 2.5.)

-- 
| Darren Salt    | linux or ds at              | nr. Ashington, | Toon
| RISC OS, Linux | youmustbejoking,demon,co,uk | Northumberland | Army
| + Output less CO2 => avoid massive flooding.    TIME IS RUNNING OUT *FAST*.

"There's nothing you can do that can't be done." - John Lennon.
-------------- next part --------------
diff -urNad rox-filer-2.5~/ROX-Filer/Options.xml rox-filer-2.5/ROX-Filer/Options.xml
--- rox-filer-2.5~/ROX-Filer/Options.xml	2006-07-31 17:19:55.000000000 +0100
+++ rox-filer-2.5/ROX-Filer/Options.xml	2006-07-31 17:20:16.945598165 +0100
@@ -370,6 +370,11 @@
       <toggle name='blackbox_hack' label='Blackbox root menus hack'>Blackbox, Fluxbox and similar window managers do not yet work well with the ROX-Filer pinboard. This option enables some workarounds. These window managers are expected to change their behaviour in new versions so that this isn't necessary.</toggle>
       <toggle name='panel_is_dock' label="Panel is a 'dock'">Disable this option if the panel stays above other windows against your wishes. Requires a restart to take effect.</toggle>
     </frame>
+    <frame label='Pinboard click commands'>
+      <entry name='pinboard_user_defined_command_0' label='Middle-click on pinboard or icon:'>The command to be executed when you middle-click on the pinboard or a pinboard icon (no distinction is made).</entry>
+      <entry name='pinboard_user_defined_command_1' label='Right-click on pinboard:'>The command to be executed when you right-click on the pinboard.</entry>
+      <label help='1'>If a command is present, then the button's normal behaviour is overridden.</label>
+    </frame> 
     <frame label='Drag and drop'>
       <toggle name='dnd_no_hostnames' label="Don't use hostnames">Some older applications don't support XDND fully and may need to have this option turned on. Use this if dragging files to an application shows a + sign on the pointer but the drop doesn't work.</toggle>
     </frame>
diff -urNad rox-filer-2.5~/ROX-Filer/src/bind.c rox-filer-2.5/ROX-Filer/src/bind.c
--- rox-filer-2.5~/ROX-Filer/src/bind.c	2006-07-31 17:19:55.000000000 +0100
+++ rox-filer-2.5/ROX-Filer/src/bind.c	2006-07-31 17:19:58.285335695 +0100
@@ -63,6 +63,8 @@
 	gboolean release = event->type == GDK_BUTTON_RELEASE;
 	gboolean select = event->button == 1; /* (old RISC OS names) */
 	gboolean adjust = event->button != 1;
+	gboolean pinboard = context == BIND_PINBOARD_ICON ||
+			      context == BIND_PINBOARD;
 
 	gboolean dclick = event->type == GDK_2BUTTON_PRESS;
 	gboolean dclick_mode =
@@ -70,14 +72,17 @@
 		(context == BIND_PINBOARD_ICON && !o_single_pinboard.int_value);
 
 	if (b > 3)
-		return ACT_IGNORE;
+		return (pinboard && press) ? ACT_PIN_USER_DEFINED : ACT_IGNORE;
 
-	if (context == BIND_PINBOARD_ICON || context == BIND_PINBOARD)
+	if (pinboard)
 		menu_button = 3;	/* Must work with window manager */
 
 	if (b == menu_button)
 		return press ? ACT_POPUP_MENU : ACT_IGNORE;
 
+	if (b == 2 && pinboard)
+		return press ? ACT_PIN_USER_DEFINED : ACT_IGNORE;
+
 	if (item && dclick && dclick_mode)
 		return shift ? ACT_EDIT_ITEM : ACT_OPEN_ITEM;
 
diff -urNad rox-filer-2.5~/ROX-Filer/src/bind.h rox-filer-2.5/ROX-Filer/src/bind.h
--- rox-filer-2.5~/ROX-Filer/src/bind.h	2006-07-31 17:19:55.000000000 +0100
+++ rox-filer-2.5/ROX-Filer/src/bind.h	2006-07-31 17:19:58.285335695 +0100
@@ -34,6 +34,7 @@
 	ACT_LASSO_CLEAR,	/* Clear selection, and start lasso drag */
 	ACT_LASSO_MODIFY,	/* Start lasso drag without clearing */
 	ACT_RESIZE,		/* Auto-resize the filer window */
+	ACT_PIN_USER_DEFINED,	/* User-defined action on the pinboard */
 } BindAction;
 
 void bind_init(void);
diff -urNad rox-filer-2.5~/ROX-Filer/src/pinboard.c rox-filer-2.5/ROX-Filer/src/pinboard.c
--- rox-filer-2.5~/ROX-Filer/src/pinboard.c	2006-07-31 17:19:56.000000000 +0100
+++ rox-filer-2.5/ROX-Filer/src/pinboard.c	2006-07-31 17:19:58.285335695 +0100
@@ -151,6 +151,8 @@
 static Option o_top_margin, o_bottom_margin, o_left_margin, o_right_margin;
 static Option o_pinboard_image_scaling;
 
+static Option o_pinboard_user_cmd[2]; /* index == button number - 2 */
+
 /* Static prototypes */
 static GType pin_icon_get_type(void);
 static void set_size_and_style(PinIcon *pi);
@@ -238,6 +240,8 @@
 
 void pinboard_init(void)
 {
+	int i;
+
 	option_add_string(&o_pinboard_fg_colour, "pinboard_fg_colour", "#fff");
 	option_add_string(&o_pinboard_bg_colour, "pinboard_bg_colour", "#888");
 	option_add_string(&o_pinboard_shadow_colour, "pinboard_shadow_colour",
@@ -265,6 +269,13 @@
 
 	option_add_int(&o_pinboard_image_scaling, "pinboard_image_scaling", 0);
 
+	for (i = 0; i < G_N_ELEMENTS (o_pinboard_user_cmd); ++i)
+	{
+		char *opt = g_strdup_printf ("pinboard_user_defined_command_%d", i);
+		option_add_string(&o_pinboard_user_cmd[i], opt, "");
+		/* string not freed, avoiding use-after-free */
+	}
+
 	option_add_notify(pinboard_check_options);
 
 	gdk_color_parse(o_pinboard_fg_colour.value, &pin_text_fg_col);
@@ -1174,6 +1185,40 @@
 				   &edge, TRUE);
 }
 
+static inline gboolean is_empty (const char *v)
+{
+	while (isspace (*v))
+		++v;
+	return !*v;
+}
+
+static gboolean spawn_user_command(int button)
+{
+	GError	*error = NULL;
+	gint	argc;
+	gchar	**argv = NULL;
+	char	*msg;
+
+	button -= 2;
+	if (button < 0 || button >= G_N_ELEMENTS (o_pinboard_user_cmd) ||
+	    is_empty (o_pinboard_user_cmd[button].value))
+		return FALSE; /* nothing to do */
+
+	if (!g_shell_parse_argv (o_pinboard_user_cmd[button].value,
+				 &argc, &argv, &error))
+	{
+		delayed_error("%s", error ? error->message : "(null)");
+		g_error_free(error);
+	}
+	else
+	{
+		rox_spawn (home_dir, argv);
+		g_strfreev (argv);
+	}
+
+	return TRUE;
+}
+
 static void perform_action(PinIcon *pi, GdkEventButton *event)
 {
 	BindAction	action;
@@ -1196,7 +1241,12 @@
 			return;
 		case ACT_POPUP_MENU:
 			dnd_motion_ungrab();
-			pinboard_show_menu(event, pi);
+			if (pi || !spawn_user_command(event->button))
+				pinboard_show_menu(event, pi);
+			return;
+		case ACT_PIN_USER_DEFINED:
+			dnd_motion_ungrab();
+			spawn_user_command(event->button);
 			return;
 		case ACT_IGNORE:
 			return;
@@ -1275,8 +1325,19 @@
 		ButtonPressMask | ButtonReleaseMask, (XEvent *) &xev);
 }
 
-#define FORWARDED_BUTTON(pi, b) ((b) == 2 || \
-	(((b) == 3 || (b) == 1) && o_forward_buttons_13.int_value && !pi))
+static inline gboolean FORWARDED_BUTTON (const PinIcon *pi, int button)
+{
+	switch (button)
+	{
+	case 1:
+	case 3:
+		return o_forward_buttons_13.int_value && !pi;
+	case 2:
+		return TRUE;
+	default:
+		return FALSE;
+	}
+}
 
 /* pi is NULL if this is a root event */
 static gboolean button_release_event(GtkWidget *widget,
@@ -1284,7 +1345,10 @@
                             	     PinIcon *pi)
 {
 	if (FORWARDED_BUTTON(pi, event->button))
-		forward_to_root(event);
+	{
+		if (spawn_user_command (event->button))
+			forward_to_root(event);
+	}
 	else if (dnd_motion_release(event))
 	{
 		if (motion_buttons_pressed == 0 && lasso_in_progress)


More information about the Pkg-rox-devel mailing list