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

Re: [E-devel] Add application key bindings from border menu....



On 12/21/2006 16:01, Ravenlock wrote:
Hello,

Here is a patch that will add a border menu item that allows you to
enter a key binding for the current app.

It utilizes the existing key binding config dialog.  When launched from
the border menu, it will immediately prompt for the binding.  It then
selects the "Defined Command" as an action, and fills in the "Action
Params" with the present app's command line args.

Quirks/Limitations:
Well, in short... the command line and args may not be exactly what you expect. For example, some apps are started via shell scripts. Firefox and Thunderbird for example. If you start them up and create a key binding in this fashion, you get firefox-bin and thunderbird bin respectively. This will not launch those apps (on my machine anyway). Additionally, complex command lines may not be as you expect either. Command lines with pipes and `command substitutions` in particular.

Comments welcome.


Ok.  Here's the latest and greatest.

An attempt was made to utilize the info in the .dektop files to help guess the correct command line. But I'm not having very good results with that. It seems, on my machine, to return less desirable command lines than otherwise. I have left the code to do this present, but disabled. Hopefully, if this patch gets committed, someone can take a look and make a decision as to whether that code should be enabled. There is a healthy comment in the code discussing the issue.

Regards


------------------------------------------------------------------------

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV


------------------------------------------------------------------------

_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel


--
Regards,
  Ravenlock
Index: e17/apps/e/src/bin/e_border.h
===================================================================
RCS file: /var/cvs/e/e17/apps/e/src/bin/e_border.h,v
retrieving revision 1.153
diff -u -r1.153 e_border.h
--- e17/apps/e/src/bin/e_border.h	30 Nov 2006 17:42:41 -0000	1.153
+++ e17/apps/e/src/bin/e_border.h	23 Dec 2006 07:11:02 -0000
@@ -412,6 +412,7 @@
    E_Config_Dialog *border_locks_dialog;
    E_Config_Dialog *border_remember_dialog;
    E_Config_Dialog *border_border_dialog;
+   E_Config_Dialog *border_keybinding_dialog;
    E_Dialog *border_prop_dialog;
    E_Menu *border_stacking_menu;
    E_Menu *border_maximize_menu;
Index: e17/apps/e/src/bin/e_int_border_menu.c
===================================================================
RCS file: /var/cvs/e/e17/apps/e/src/bin/e_int_border_menu.c,v
retrieving revision 1.53
diff -u -r1.53 e_int_border_menu.c
--- e17/apps/e/src/bin/e_int_border_menu.c	25 Nov 2006 20:40:27 -0000	1.53
+++ e17/apps/e/src/bin/e_int_border_menu.c	23 Dec 2006 07:11:08 -0000
@@ -31,6 +31,7 @@
 static void _e_border_menu_cb_raise(void *data, E_Menu *m, E_Menu_Item *mi);
 static void _e_border_menu_cb_lower(void *data, E_Menu *m, E_Menu_Item *mi);
 static void _e_border_menu_cb_state_pre(void *data, E_Menu *m, E_Menu_Item *mi);
+static void _e_border_menu_cb_keybinding_add(void *data, E_Menu *m, E_Menu_Item *mi);
 
 EAPI void
 e_int_border_menu_show(E_Border *bd, Evas_Coord x, Evas_Coord y, int key, Ecore_X_Time timestamp)
@@ -268,6 +269,12 @@
 	e_menu_item_label_set(mi, _("Add App To Launcher"));
 	e_menu_item_submenu_pre_callback_set(mi, _e_border_menu_cb_icon_add_pre, bd);
 	e_util_menu_item_edje_icon_set(mi, "enlightenment/applications");
+	  
+	mi = e_menu_item_new(m);
+	e_menu_item_label_set(mi, _("Add Keybinding"));
+	e_menu_item_callback_set(mi, _e_border_menu_cb_keybinding_add, bd);
+	e_util_menu_item_edje_icon_set(mi, "enlightenment/keys");
+     
      }
    
    mi = e_menu_item_new(m);
@@ -920,3 +927,16 @@
 				  "e/widgets/border/default/fullscreen");
      }
 }
+
+static void 
+_e_border_menu_cb_keybinding_add(void *data, E_Menu *m, E_Menu_Item *mi) 
+{
+   E_Border *bd;
+   
+   bd = data;
+   if (!bd) return;
+   if (bd->border_keybinding_dialog) return;
+   
+   bd->border_keybinding_dialog = e_int_config_keybindings_border_add(bd);
+
+}
Index: e17/apps/e/src/bin/e_int_config_keybindings.c
===================================================================
RCS file: /var/cvs/e/e17/apps/e/src/bin/e_int_config_keybindings.c,v
retrieving revision 1.49
diff -u -r1.49 e_int_config_keybindings.c
--- e17/apps/e/src/bin/e_int_config_keybindings.c	16 Dec 2006 20:32:40 -0000	1.49
+++ e17/apps/e/src/bin/e_int_config_keybindings.c	23 Dec 2006 07:11:10 -0000
@@ -34,6 +34,9 @@
 static char *_key_binding_text_get(E_Config_Binding_Key *bi);
 static void _auto_apply_changes(E_Config_Dialog_Data *cfdata);
 static void _find_key_binding_action(const char *action, const char *params, int *g, int *a, int *n);
+static char *_border_cmdln_args_get(E_Border *border);
+static char *_app_cmdln_args_get(E_App *app);
+static char *_cmdln_args_get(E_Border *border);
 
 /********* Sorting ************************/
 static int _key_binding_sort_cb(void *d1, void *d2);
@@ -45,6 +48,7 @@
 
 struct _E_Config_Dialog_Data
 {
+   E_Border *border;
    Evas *evas;
    struct
      {
@@ -59,7 +63,10 @@
 	char *cur;
 	int cur_act;
 	int add;
-
+	
+	int border_add;
+	char *border_params;
+   
 	E_Dialog *dia;
 	Ecore_X_Window bind_win;
 	Evas_List *handlers;
@@ -96,6 +103,25 @@
    return cfd;
 }
 
+EAPI E_Config_Dialog * 
+e_int_config_keybindings_border_add(E_Border *border)
+{
+   E_Config_Dialog *cfd;
+   char *buf;
+   
+   cfd = e_int_config_keybindings(NULL);
+   if (!cfd) return cfd;
+   cfd->cfdata->border = border;
+   
+   cfd->cfdata->locals.border_params = _cmdln_args_get(border);
+   
+   /* Press our "Add" button */
+   cfd->cfdata->locals.border_add = 1;
+   _add_key_binding_cb(cfd->cfdata, NULL);
+      
+   return cfd;
+}
+
 static void
 _fill_data(E_Config_Dialog_Data *cfdata)
 {
@@ -123,7 +149,7 @@
 	bi2->any_mod = bi->any_mod;
 	bi2->action = bi->action == NULL ? NULL : evas_stringshare_add(bi->action);
 	bi2->params = bi->params == NULL ? NULL : evas_stringshare_add(bi->params);
-
+   
 	cfdata->binding.key = evas_list_append(cfdata->binding.key, bi2);
      }
 }
@@ -153,13 +179,19 @@
 	if (bi->params) evas_stringshare_del(bi->params);
 	E_FREE(bi);
 	cfdata->binding.key = evas_list_remove_list(cfdata->binding.key, cfdata->binding.key);
-     }
-
+     }       
+     
    if (cfdata->locals.cur) free(cfdata->locals.cur);
    if (cfdata->locals.binding) free(cfdata->locals.binding);
    if (cfdata->locals.action) free(cfdata->locals.action);
    if (cfdata->locals.params) free(cfdata->locals.params);
-
+      
+   if (cfdata->locals.border_add)
+     {
+	if (cfdata->locals.border_params) free(cfdata->locals.border_params);
+	   cfdata->border->border_keybinding_dialog = NULL;
+     }
+   
    free(cfdata);
 }
 
@@ -290,7 +322,7 @@
 
 	for (l2 = actg->acts, a = 0; l2; l2 = l2->next, a++)
 	  {
-	     actd = l2->data;
+             actd = l2->data;
 
 	     snprintf(buf, sizeof(buf), "%d %d", g, a);
 	     e_widget_ilist_append(cfdata->gui.o_action_list, NULL, actd->act_name,
@@ -1026,7 +1058,7 @@
 	     if (ev->modifiers & ECORE_X_LOCK_NUM) 
 	       mod |= ECORE_X_LOCK_NUM;
 	      */
-	     if (cfdata->locals.add)
+	     if ((cfdata->locals.add) || (cfdata->locals.border_add))
 	       {
 		  found = 0;
 		  for (l = cfdata->binding.key; l && !found; l = l->next)
@@ -1056,15 +1088,23 @@
 
 	     if (!found)
 	       {
-		  if (cfdata->locals.add)
+		  if ((cfdata->locals.add) || (cfdata->locals.border_add))
 		    {
 		       bi = E_NEW(E_Config_Binding_Key, 1);
 
 		       bi->context = E_BINDING_CONTEXT_ANY;
 		       bi->modifiers = mod;
 		       bi->key = evas_stringshare_add(ev->keyname);
-		       bi->action = NULL;
-		       bi->params = NULL;
+		       if (!cfdata->locals.border_add)
+			 {
+			    bi->action = NULL;
+			    bi->params = NULL;
+			 }
+		       else
+			 {
+			     bi->action = evas_stringshare_add("exec");
+			     bi->params = evas_stringshare_add(cfdata->locals.border_params);
+			 }
 		       bi->any_mod = 0;
 
 		       cfdata->binding.key = evas_list_append(cfdata->binding.key, bi);
@@ -1082,7 +1122,7 @@
 			 }
 		    } 
 
-		  if (cfdata->locals.add) 
+		  if ((cfdata->locals.add) || (cfdata->locals.border_add))
 		    { 
 		       _update_key_binding_list(cfdata);
 
@@ -1091,11 +1131,14 @@
 			    if (l->data == bi) break;
 			 }
 		       e_widget_ilist_selected_set(cfdata->gui.o_binding_list, n);
-		       e_widget_ilist_unselect(cfdata->gui.o_action_list);
-		       if (cfdata->locals.action) free(cfdata->locals.action);
-		       cfdata->locals.action = strdup("");
-		       e_widget_entry_clear(cfdata->gui.o_params);
-		       e_widget_disabled_set(cfdata->gui.o_params, 1);
+		       if (!cfdata->locals.border_add)
+			  {
+			     e_widget_ilist_unselect(cfdata->gui.o_action_list);
+			     if (cfdata->locals.action) free(cfdata->locals.action);
+				cfdata->locals.action = strdup("");
+			     e_widget_entry_clear(cfdata->gui.o_params);
+			     e_widget_disabled_set(cfdata->gui.o_params, 1);
+			  }
 		    }
 		  else
 		    {
@@ -1312,3 +1355,97 @@
    if (!b[0]) return strdup(TEXT_NONE_ACTION_KEY);
    return strdup(b);
 }
+
+static char *
+_cmdln_args_get(E_Border *border)
+{
+   char *buf1 = NULL;
+   char *buf2 = NULL;
+
+   if (!border) return NULL;
+
+   /* 
+    * FIXME: (Fix Something!)
+    *   Less than desirable effects can be had by using the command line
+    *   provided by the E_App object.  This obtains its executable, and 
+    *   executable args from the .desktop file (AFAIK).  However in certain 
+    *   situations there's a bit of ambiguity as to *which* .desktop
+    *   file should be used.  Resulting in undesired command line args
+    *   being returned.  In an effort to keep it simple, I am returning
+    *   the command line from the E_App.  I do this because if need be,
+    *   at least, the user can reconfigure their .desktop files to alleviate
+    *   the ambiguities.  Additionally,  If the code responsible for 
+    *   selecting the appropriate .desktop file is "fixed" then this should
+    *   actually be the best solution.
+    * 
+    * NOTE:  This is DISABLED.  I return the command line from the 
+    *   E_Border ICCCM command bits.  :)
+    */
+   buf1 = NULL; /* = _app_cmdln_args_get(border->app); */
+   buf2 = _border_cmdln_args_get(border);
+   if ((!buf1) && (!buf2)) return NULL;
+      
+   if ((buf1) && (buf2))
+     {
+     	return buf1;
+     }
+   else
+     if (buf1)
+	return buf1;
+     else
+	return buf2;	
+   
+}
+
+static char *
+_border_cmdln_args_get(E_Border *border)
+{  
+   int i;
+   char *buf = NULL;
+   char *ws = NULL;
+
+   if (!border) return NULL;
+
+   buf = strdup("");
+   for (i = 0; i <= border->client.icccm.command.argc - 1; i++)
+     {
+        ws = strstr(border->client.icccm.command.argv[i]," ");
+        if (!ws) 
+	  {
+	     buf = realloc(buf, strlen(buf) + strlen(border->client.icccm.command.argv[i]) + 2);
+	     strcat(buf, border->client.icccm.command.argv[i]);
+	  }
+        else
+	  {
+	     buf = realloc(buf, strlen(buf) + strlen(border->client.icccm.command.argv[i]) + 4);        
+	     strcat(buf, "\"");
+	     strcat(buf, border->client.icccm.command.argv[i]);        
+	     strcat(buf, "\"");
+	  }   
+        strcat(buf, " ");
+     }
+  
+   return buf;  
+  
+}
+
+static char *
+_app_cmdln_args_get(E_App *app)
+{
+   char *buf = NULL;
+
+   if (!app) return NULL;
+   if (!app->desktop) return NULL;
+   
+   if (app->exe)
+   	buf = strdup(app->exe);
+   if (app->exe_params)
+     {
+     	buf = realloc(buf, strlen(buf) + strlen(app->exe_params) + 2);
+     	strcat(buf, " ");
+   	strcat(buf, app->exe_params);
+     }
+  
+   return buf;
+
+}
Index: e17/apps/e/src/bin/e_int_config_keybindings.h
===================================================================
RCS file: /var/cvs/e/e17/apps/e/src/bin/e_int_config_keybindings.h,v
retrieving revision 1.4
diff -u -r1.4 e_int_config_keybindings.h
--- e17/apps/e/src/bin/e_int_config_keybindings.h	11 Oct 2006 08:46:52 -0000	1.4
+++ e17/apps/e/src/bin/e_int_config_keybindings.h	23 Dec 2006 07:11:10 -0000
@@ -4,6 +4,7 @@
 #define E_INT_CONFIG_KEYBINDINGS_H
 
 EAPI E_Config_Dialog *e_int_config_keybindings(E_Container *con);
+EAPI E_Config_Dialog *e_int_config_keybindings_border_add(E_Border *border);
 
 #endif
 #endif