Index: Makefile.am
===================================================================
*** Makefile.am	(.../3.4.7.2)	(revision 30)
--- Makefile.am	(.../trunk)	(revision 30)
***************
*** 158,163 ****
--- 158,164 ----
  	openbox/actions/all.c \
  	openbox/actions/all.h \
  	openbox/actions/addremovedesktop.c \
+ 	openbox/actions/remember.c \
  	openbox/actions/breakchroot.c \
  	openbox/actions/close.c \
  	openbox/actions/cyclewindows.c \
Index: openbox/actions/remember.c
===================================================================
*** openbox/actions/remember.c	(.../3.4.7.2)	(revision 0)
--- openbox/actions/remember.c	(.../trunk)	(revision 30)
***************
*** 0 ****
--- 1,133 ----
+ 
+ #include "openbox/actions.h"
+ #include "openbox/client.h"
+ #include "openbox/screen.h"
+ #include "openbox/frame.h"
+ #include <glib.h>
+ #include <X11/Xlib.h>
+ 
+ /* 
+ OpenBox actions to remember/recall windows as a hotkey action
+ 
+ Daniel Ramsay <daniel@dretzq.org.uk> 2009-12-29
+ 
+ Usage info:
+ 
+ Configure a keybinding in rc.xml to execute the "Remember" action.  
+ 
+ <keybind action="C-F5">
+   <action name="Remember"><id>F5</id></action>
+ </keybind>
+ 
+ Remember requires one parameter, "id".  
+ This id parameter is currently not used.
+ 
+ When a configured "remember" keybind action is invoked, the remember action will save the currently focussed 
+ window's XID against that key.
+ 
+ Subsequently invoking the keybinding will activate the stored client.
+ 
+ If a remembered window has been closed/deleted in the meantime, the stored XID is overwritten and the
+ hotkey can be reassigned to a new window.
+ 
+ A future version will include a separate action to clear hotkey->window assignments, and separate 
+ actions to remember and recall windows for a given slot "id" (which is what the ID parameter will be for).
+ 
+ */
+ 
+ static gpointer remember_setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
+ static void     remember_free_func(gpointer options);
+ static gboolean remember_run_func(ObActionsData *data, gpointer options);
+ 
+ /*
+ Simple options struct retains the ID value and the selected window ID for the 
+ keybinding.
+ */
+ 
+ typedef struct {
+ 	
+     gchar  *id;		/* The hotkey ID value */
+     Window xid;		/* The stored Window ID, or -1 if none */
+ } Options;
+ 
+ /*
+ Action module entrypoint
+ */
+ 
+ void action_remember_startup(void)
+ {
+     actions_register("Remember",
+                      remember_setup_func,
+                      remember_free_func,
+                      remember_run_func,
+                      NULL, NULL);
+ }
+ 
+ /*
+ Setup options structure for this keybinding
+ */
+ 
+ static gpointer remember_setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node) {
+     xmlNodePtr n;
+     Options *o = g_new0(Options,1);
+ 
+     if ((n = parse_find_node("id", node))) {
+ 	o->id = parse_string(doc, n);
+ 	o->xid = -1;
+     } else {
+ 	g_print("Could not extract id element.\n");
+ 	return NULL;
+     }
+ 
+     return (gpointer)o;
+ }
+ 
+ /*
+ Free the options structure stored with this keybinding
+ */
+ 
+ static void remember_free_func(gpointer opts) {
+ 
+     Options *o = opts;
+     g_free(o->id);
+     g_free(opts);
+ }
+ 
+ /*
+ Function run when keybinding is invoked
+ */
+ 
+ static gboolean remember_run_func(ObActionsData *data, gpointer opts) {
+ 
+     Options *o = opts;
+     gboolean found = FALSE;
+ 
+     /* callback for list search */
+     void activate_list_cb(gpointer data, gpointer user_data) {
+         Options *o = user_data;
+         ObClient *client = data;
+         if (client->window == o->xid) {
+             /* Activate matching client */
+             client_activate(client, FALSE, TRUE, TRUE, TRUE);
+             /* Sets the found flag when a window with the matching ID is found */
+             found = TRUE;
+         }
+     }
+ 
+     /* If this hotkey has no window ID stored */
+     if (o->xid == -1) {
+         /* Remember it in the options structure */
+         o->xid = data->client->window;
+     } else {
+         /* Otherwise, search for the window ID in the client list */
+         g_list_foreach(client_list, activate_list_cb, o);
+ 
+         /* If it isn't found, clear the window ID that was stored */
+         if (!found) {
+             o->xid = -1;
+             return FALSE;
+         }
+     }
+     return TRUE;
+         
+ }
Index: openbox/actions/all.c
===================================================================
*** openbox/actions/all.c	(.../3.4.7.2)	(revision 30)
--- openbox/actions/all.c	(.../trunk)	(revision 30)
***************
*** 39,42 ****
--- 39,43 ----
      action_growtoedge_startup();
      action_focustobottom_startup();
      action_shadelowerraise_startup();
+     action_remember_startup();
  }
Index: openbox/actions/all.h
===================================================================
*** openbox/actions/all.h	(.../3.4.7.2)	(revision 30)
--- openbox/actions/all.h	(.../trunk)	(revision 30)
***************
*** 40,44 ****
--- 40,45 ----
  void action_growtoedge_startup(void);
  void action_focustobottom_startup(void);
  void action_shadelowerraise_startup(void);
+ void action_remember_startup(void);
  
  #endif
