From 8516f1e2a21a374127ccfa3f7b8de2443e67fe33 Mon Sep 17 00:00:00 2001
From: Mark Tiefenbruck <mark@fluxbox.org>
Date: Sat, 15 Dec 2007 19:36:01 -0800
Subject: changed CommandRegistry to a template class, renamed to
 ObjectRegistry<Type>

---
 src/ClockTool.cc            |   6 +-
 src/CommandDialog.cc        |   9 ++-
 src/CurrentWindowCmd.cc     | 108 +++++++++++++++---------------
 src/FbCommands.cc           |  56 ++++++++--------
 src/FbTk/CommandRegistry.cc |  96 --------------------------
 src/FbTk/CommandRegistry.hh | 130 -----------------------------------
 src/FbTk/LogicCommands.cc   |  24 +++----
 src/FbTk/MacroCommand.cc    |   8 +--
 src/FbTk/Makefile.am        |   2 +-
 src/FbTk/ObjectRegistry.hh  | 160 ++++++++++++++++++++++++++++++++++++++++++++
 src/IconbarTool.cc          |   4 +-
 src/Keys.cc                 |   4 +-
 src/MenuCreator.cc          |  10 +--
 src/Screen.cc               |  12 ++--
 src/ToolFactory.cc          |   6 +-
 src/Toolbar.cc              |   4 +-
 src/WorkspaceCmd.cc         |  53 ++++++++-------
 src/WorkspaceMenu.cc        |   4 +-
 18 files changed, 318 insertions(+), 378 deletions(-)
 delete mode 100644 src/FbTk/CommandRegistry.cc
 delete mode 100644 src/FbTk/CommandRegistry.hh
 create mode 100644 src/FbTk/ObjectRegistry.hh

diff --git a/src/ClockTool.cc b/src/ClockTool.cc
index 55973fb..b396999 100644
--- a/src/ClockTool.cc
+++ b/src/ClockTool.cc
@@ -26,7 +26,7 @@
 
 #include "ToolTheme.hh"
 #include "Screen.hh"
-#include "FbTk/CommandRegistry.hh"
+#include "FbTk/ObjectRegistry.hh"
 #include "CommandDialog.hh"
 #include "fluxbox.hh"
 
@@ -128,7 +128,7 @@ public:
 
         CommandDialog *dialog = new CommandDialog(*screen, "Edit Clock Format", 
                                                   "SetResourceValue " + resourcename + " ");
-        FbTk::RefCount<FbTk::Command> cmd(FbTk::CommandRegistry::instance().parseLine("reconfigure"));
+        FbTk::RefCount<FbTk::Command> cmd(FbTk::ObjectRegistry<FbTk::Command>::instance().parse("reconfigure"));
         dialog->setPostCommand(cmd);
         dialog->setText(screen->resourceManager().resourceValue(resourcename));
         dialog->show();
@@ -169,7 +169,7 @@ ClockTool::ClockTool(const FbTk::FbWindow &parent,
     m_button.setGC(m_theme.textGC());
 
     // setup menu
-    FbTk::RefCount<FbTk::Command> saverc(FbTk::CommandRegistry::instance().parseLine("saverc"));
+    FbTk::RefCount<FbTk::Command> saverc(FbTk::ObjectRegistry<FbTk::Command>::instance().parse("saverc"));
     FbTk::MenuItem *item = new ClockMenuItem(*this);
     item->setCommand(saverc);
     menu.insert(item);
diff --git a/src/CommandDialog.cc b/src/CommandDialog.cc
index 436a942..4c07a93 100644
--- a/src/CommandDialog.cc
+++ b/src/CommandDialog.cc
@@ -27,7 +27,7 @@
 #include "Screen.hh"
 #include "FbWinFrameTheme.hh"
 #include "WinClient.hh"
-#include "FbTk/CommandRegistry.hh"
+#include "FbTk/ObjectRegistry.hh"
 #include "FocusControl.hh"
 #include "fluxbox.hh"
 
@@ -139,8 +139,7 @@ void CommandDialog::keyPressEvent(XKeyEvent &event) {
     if (ks == XK_Return) {
         hide(); // hide and return focus to a FluxboxWindow
         // create command from line
-        auto_ptr<FbTk::Command> cmd(FbTk::CommandRegistry::instance().
-            parseLine(m_precommand + m_textbox.text()));
+        auto_ptr<FbTk::Command> cmd(FbTk::ObjectRegistry<FbTk::Command>::instance().parse(m_precommand + m_textbox.text()));
         if (cmd.get())
             cmd->execute();
         // post execute
@@ -170,8 +169,8 @@ void CommandDialog::tabComplete() {
             return;
         }
 
-        FbTk::CommandRegistry::CreatorMap::const_iterator it = FbTk::CommandRegistry::instance().commandMap().begin();
-        const FbTk::CommandRegistry::CreatorMap::const_iterator it_end = FbTk::CommandRegistry::instance().commandMap().end();
+        FbTk::ObjectRegistry<FbTk::Command>::CreatorMap::const_iterator it = FbTk::ObjectRegistry<FbTk::Command>::instance().creatorMap().begin();
+        const FbTk::ObjectRegistry<FbTk::Command>::CreatorMap::const_iterator it_end = FbTk::ObjectRegistry<FbTk::Command>::instance().creatorMap().end();
         vector<string> matches;
         for (; it != it_end; ++it) {
             if ((*it).first.find(prefix) == 0) {
diff --git a/src/CurrentWindowCmd.cc b/src/CurrentWindowCmd.cc
index 33d8e8a..d7b05ab 100644
--- a/src/CurrentWindowCmd.cc
+++ b/src/CurrentWindowCmd.cc
@@ -31,13 +31,15 @@
 #include "WinClient.hh"
 
 #include "FocusControl.hh"
-#include "FbTk/CommandRegistry.hh"
+#include "FbTk/ObjectRegistry.hh"
 #include "FbTk/stringstream.hh"
 #include "FbTk/StringUtil.hh"
 
 #include <string>
 #include <vector>
 
+using FbTk::Command;
+
 namespace {
 
 FbTk::Command *createCurrentWindowCmd(const std::string &command,
@@ -89,35 +91,35 @@ FbTk::Command *createCurrentWindowCmd(const std::string &command,
     return 0;
 }
 
-REGISTER_COMMAND_PARSER(minimizewindow, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(minimize, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(iconify, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(maximizewindow, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(maximize, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(maximizevertical, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(maximizehorizontal, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(raise, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(raiselayer, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(lower, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(lowerlayer, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(activate, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(focus, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(close, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(killwindow, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(kill, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(shade, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(shadewindow, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(shadeon, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(shadeoff, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(stick, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(stickwindow, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(toggledecor, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(nexttab, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(prevtab, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(movetableft, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(movetabright, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(detachclient, createCurrentWindowCmd);
-REGISTER_COMMAND_PARSER(windowmenu, createCurrentWindowCmd);
+REGISTER_OBJECT_PARSER(minimizewindow, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(minimize, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(iconify, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(maximizewindow, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(maximize, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(maximizevertical, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(maximizehorizontal, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(raise, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(raiselayer, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(lower, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(lowerlayer, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(activate, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(focus, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(close, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(killwindow, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(kill, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(shade, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(shadewindow, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(shadeon, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(shadeoff, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(stick, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(stickwindow, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(toggledecor, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(nexttab, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(prevtab, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(movetableft, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(movetabright, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(detachclient, createCurrentWindowCmd, Command);
+REGISTER_OBJECT_PARSER(windowmenu, createCurrentWindowCmd, Command);
 
 }; // end anonymous namespace
 
@@ -184,14 +186,14 @@ FbTk::Command *parseIntCmd(const string &command, const string &args,
     return 0;
 }
 
-REGISTER_COMMAND_PARSER(sethead, parseIntCmd);
-REGISTER_COMMAND_PARSER(tab, parseIntCmd);
-REGISTER_COMMAND_PARSER(sendtonextworkspace, parseIntCmd);
-REGISTER_COMMAND_PARSER(sendtoprevworkspace, parseIntCmd);
-REGISTER_COMMAND_PARSER(taketonextworkspace, parseIntCmd);
-REGISTER_COMMAND_PARSER(taketoprevworkspace, parseIntCmd);
-REGISTER_COMMAND_PARSER(sendtoworkspace, parseIntCmd);
-REGISTER_COMMAND_PARSER(taketoworkspace, parseIntCmd);
+REGISTER_OBJECT_PARSER(sethead, parseIntCmd, Command);
+REGISTER_OBJECT_PARSER(tab, parseIntCmd, Command);
+REGISTER_OBJECT_PARSER(sendtonextworkspace, parseIntCmd, Command);
+REGISTER_OBJECT_PARSER(sendtoprevworkspace, parseIntCmd, Command);
+REGISTER_OBJECT_PARSER(taketonextworkspace, parseIntCmd, Command);
+REGISTER_OBJECT_PARSER(taketoprevworkspace, parseIntCmd, Command);
+REGISTER_OBJECT_PARSER(sendtoworkspace, parseIntCmd, Command);
+REGISTER_OBJECT_PARSER(taketoworkspace, parseIntCmd, Command);
 
 }; // end anonymous namespace
 
@@ -254,7 +256,7 @@ void GoToTabCmd::real_execute() {
     (*it)->focus();
 }
 
-REGISTER_COMMAND(startmoving, StartMovingCmd);
+REGISTER_OBJECT(startmoving, StartMovingCmd, Command);
 
 void StartMovingCmd::real_execute() {
     const XEvent &last = Fluxbox::instance()->lastEvent();
@@ -297,7 +299,7 @@ FbTk::Command *StartResizingCmd::parse(const string &cmd, const string &args,
     return new StartResizingCmd(mode);
 }
 
-REGISTER_COMMAND_PARSER(startresizing, StartResizingCmd::parse);
+REGISTER_OBJECT_PARSER(startresizing, StartResizingCmd::parse, Command);
 
 void StartResizingCmd::real_execute() {
     const XEvent &last = Fluxbox::instance()->lastEvent();
@@ -332,11 +334,11 @@ FbTk::Command *MoveCmd::parse(const string &command, const string &args,
     return new MoveCmd(dx, dy);
 }
 
-REGISTER_COMMAND_PARSER(move, MoveCmd::parse);
-REGISTER_COMMAND_PARSER(moveright, MoveCmd::parse);
-REGISTER_COMMAND_PARSER(moveleft, MoveCmd::parse);
-REGISTER_COMMAND_PARSER(moveup, MoveCmd::parse);
-REGISTER_COMMAND_PARSER(movedown, MoveCmd::parse);
+REGISTER_OBJECT_PARSER(move, MoveCmd::parse, Command);
+REGISTER_OBJECT_PARSER(moveright, MoveCmd::parse, Command);
+REGISTER_OBJECT_PARSER(moveleft, MoveCmd::parse, Command);
+REGISTER_OBJECT_PARSER(moveup, MoveCmd::parse, Command);
+REGISTER_OBJECT_PARSER(movedown, MoveCmd::parse, Command);
 
 MoveCmd::MoveCmd(const int step_size_x, const int step_size_y) :
   m_step_size_x(step_size_x), m_step_size_y(step_size_y) { }
@@ -364,10 +366,10 @@ FbTk::Command *ResizeCmd::parse(const string &command, const string &args,
     return new ResizeCmd(dx, dy);
 }
 
-REGISTER_COMMAND_PARSER(resize, ResizeCmd::parse);
-REGISTER_COMMAND_PARSER(resizeto, ResizeCmd::parse);
-REGISTER_COMMAND_PARSER(resizehorizontal, ResizeCmd::parse);
-REGISTER_COMMAND_PARSER(resizevertical, ResizeCmd::parse);
+REGISTER_OBJECT_PARSER(resize, ResizeCmd::parse, Command);
+REGISTER_OBJECT_PARSER(resizeto, ResizeCmd::parse, Command);
+REGISTER_OBJECT_PARSER(resizehorizontal, ResizeCmd::parse, Command);
+REGISTER_OBJECT_PARSER(resizevertical, ResizeCmd::parse, Command);
 
 ResizeCmd::ResizeCmd(const int step_size_x, const int step_size_y) :
     m_step_size_x(step_size_x), m_step_size_y(step_size_y) { }
@@ -428,7 +430,7 @@ FbTk::Command *MoveToCmd::parse(const string &cmd, const string &args,
 
 }
 
-REGISTER_COMMAND_PARSER(moveto, MoveToCmd::parse);
+REGISTER_OBJECT_PARSER(moveto, MoveToCmd::parse, Command);
 
 MoveToCmd::MoveToCmd(const int step_size_x, const int step_size_y, const unsigned int refc) :
     m_step_size_x(step_size_x), m_step_size_y(step_size_y), m_refc(refc) { }
@@ -465,7 +467,7 @@ void ResizeToCmd::real_execute() {
         fbwindow().resize(m_step_size_x, m_step_size_y);
 }
 
-REGISTER_COMMAND(fullscreen, FullscreenCmd);
+REGISTER_OBJECT(fullscreen, FullscreenCmd, Command);
 
 FullscreenCmd::FullscreenCmd() { }
 void FullscreenCmd::real_execute() {
@@ -497,7 +499,7 @@ FbTk::Command *SetAlphaCmd::parse(const string &command, const string &args,
     return new SetAlphaCmd(focused, relative, unfocused, un_rel);
 }
 
-REGISTER_COMMAND_PARSER(setalpha, SetAlphaCmd::parse);
+REGISTER_OBJECT_PARSER(setalpha, SetAlphaCmd::parse, Command);
 
 SetAlphaCmd::SetAlphaCmd(int focused, bool relative,
                          int unfocused, bool un_relative) :
@@ -529,7 +531,7 @@ void SetAlphaCmd::real_execute() {
         fbwindow().setUnfocusedAlpha(m_unfocus);
 }
 
-REGISTER_BOOLCOMMAND_WITH_ARGS(matches, MatchCmd);
+REGISTER_OBJECT_WITH_ARGS_NSBASE(matches, MatchCmd, FbTk, BoolCommand);
 
 bool MatchCmd::real_execute() {
     return m_pat.match(winclient());
diff --git a/src/FbCommands.cc b/src/FbCommands.cc
index 0d4e0e3..747eb3c 100644
--- a/src/FbCommands.cc
+++ b/src/FbCommands.cc
@@ -33,7 +33,7 @@
 
 #include "FbTk/Theme.hh"
 #include "FbTk/Menu.hh"
-#include "FbTk/CommandRegistry.hh"
+#include "FbTk/ObjectRegistry.hh"
 #include "FbTk/StringUtil.hh"
 #include "FbTk/stringstream.hh"
 
@@ -123,9 +123,11 @@ void showMenu(const BScreen &screen, FbTk::Menu &menu) {
 
 namespace FbCommands {
 
-REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(exec, FbCommands::ExecuteCmd);
-REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(execute, FbCommands::ExecuteCmd);
-REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(execcommand, FbCommands::ExecuteCmd);
+using FbTk::Command;
+
+REGISTER_UNTRUSTED_OBJECT_WITH_ARGS(exec, FbCommands::ExecuteCmd, Command);
+REGISTER_UNTRUSTED_OBJECT_WITH_ARGS(execute, FbCommands::ExecuteCmd, Command);
+REGISTER_UNTRUSTED_OBJECT_WITH_ARGS(execcommand, FbCommands::ExecuteCmd, Command);
 
 ExecuteCmd::ExecuteCmd(const string &cmd, int screen_num):m_cmd(cmd), m_screen_num(screen_num) {
 
@@ -193,9 +195,9 @@ FbTk::Command *ExportCmd::parse(const string &command, const string &args,
     return new ExportCmd(name, value);
 }
 
-REGISTER_COMMAND_PARSER(setenv, ExportCmd::parse);
-REGISTER_COMMAND_PARSER(export, ExportCmd::parse);
-REGISTER_COMMAND_PARSER(setresourcevalue, ExportCmd::parse);
+REGISTER_OBJECT_PARSER(setenv, ExportCmd::parse, Command);
+REGISTER_OBJECT_PARSER(export, ExportCmd::parse, Command);
+REGISTER_OBJECT_PARSER(setresourcevalue, ExportCmd::parse, Command);
 
 ExportCmd::ExportCmd(const string& name, const string& value) :
     m_name(name), m_value(value) {
@@ -233,20 +235,20 @@ void ExportCmd::execute() {
     }
 }
 
-REGISTER_COMMAND(exit, FbCommands::ExitFluxboxCmd);
-REGISTER_COMMAND(quit, FbCommands::ExitFluxboxCmd);
+REGISTER_OBJECT(exit, FbCommands::ExitFluxboxCmd, Command);
+REGISTER_OBJECT(quit, FbCommands::ExitFluxboxCmd, Command);
 
 void ExitFluxboxCmd::execute() {
     Fluxbox::instance()->shutdown();
 }
 
-REGISTER_COMMAND(saverc, FbCommands::SaveResources);
+REGISTER_OBJECT(saverc, FbCommands::SaveResources, Command);
 
 void SaveResources::execute() {
     Fluxbox::instance()->save_rc();
 }
 
-REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(restart, FbCommands::RestartFluxboxCmd);
+REGISTER_UNTRUSTED_OBJECT_WITH_ARGS(restart, FbCommands::RestartFluxboxCmd, Command);
 
 RestartFluxboxCmd::RestartFluxboxCmd(const string &cmd):m_cmd(cmd){
 }
@@ -258,21 +260,21 @@ void RestartFluxboxCmd::execute() {
         Fluxbox::instance()->restart(m_cmd.c_str());
 }
 
-REGISTER_COMMAND(reconfigure, FbCommands::ReconfigureFluxboxCmd);
-REGISTER_COMMAND(reconfig, FbCommands::ReconfigureFluxboxCmd);
+REGISTER_OBJECT(reconfigure, FbCommands::ReconfigureFluxboxCmd, Command);
+REGISTER_OBJECT(reconfig, FbCommands::ReconfigureFluxboxCmd, Command);
 
 void ReconfigureFluxboxCmd::execute() {
     Fluxbox::instance()->reconfigure();
 }
 
-REGISTER_COMMAND(reloadstyle, FbCommands::ReloadStyleCmd);
+REGISTER_OBJECT(reloadstyle, FbCommands::ReloadStyleCmd, Command);
 
 void ReloadStyleCmd::execute() {
     SetStyleCmd cmd(Fluxbox::instance()->getStyleFilename());
     cmd.execute();
 }
 
-REGISTER_COMMAND_WITH_ARGS(setstyle, FbCommands::SetStyleCmd);
+REGISTER_OBJECT_WITH_ARGS(setstyle, FbCommands::SetStyleCmd, Command);
 
 SetStyleCmd::SetStyleCmd(const string &filename):m_filename(filename) {
 
@@ -285,7 +287,7 @@ void SetStyleCmd::execute() {
                                         Fluxbox::instance()->getStyleOverlayFilename());
 }
 
-REGISTER_COMMAND_WITH_ARGS(keymode, FbCommands::KeyModeCmd);
+REGISTER_OBJECT_WITH_ARGS(keymode, FbCommands::KeyModeCmd, Command);
 
 KeyModeCmd::KeyModeCmd(const string &arguments):m_keymode(arguments),m_end_args("None Escape") {
     string::size_type second_pos = m_keymode.find_first_of(" \t", 0);
@@ -302,7 +304,7 @@ void KeyModeCmd::execute() {
     Fluxbox::instance()->keys()->keyMode(m_keymode);
 }
 
-REGISTER_COMMAND(hidemenus, FbCommands::HideMenuCmd);
+REGISTER_OBJECT(hidemenus, FbCommands::HideMenuCmd, Command);
 
 void HideMenuCmd::execute() {
     FbTk::Menu::hideShownMenu();
@@ -316,7 +318,7 @@ FbTk::Command *ShowClientMenuCmd::parse(const string &command,
     return new ShowClientMenuCmd(opts, pat);
 }
 
-REGISTER_COMMAND_PARSER(clientmenu, ShowClientMenuCmd::parse);
+REGISTER_OBJECT_PARSER(clientmenu, ShowClientMenuCmd::parse, Command);
 
 void ShowClientMenuCmd::execute() {
     BScreen *screen = Fluxbox::instance()->mouseScreen();
@@ -339,7 +341,7 @@ void ShowClientMenuCmd::execute() {
     ::showMenu(*screen, **m_menu);
 }
 
-REGISTER_COMMAND_WITH_ARGS(custommenu, FbCommands::ShowCustomMenuCmd);
+REGISTER_OBJECT_WITH_ARGS(custommenu, FbCommands::ShowCustomMenuCmd, Command);
 
 ShowCustomMenuCmd::ShowCustomMenuCmd(const string &arguments) : custom_menu_file(arguments) {}
 
@@ -354,7 +356,7 @@ void ShowCustomMenuCmd::execute() {
     ::showMenu(*screen, **m_menu);
 }
 
-REGISTER_COMMAND(rootmenu, FbCommands::ShowRootMenuCmd);
+REGISTER_OBJECT(rootmenu, FbCommands::ShowRootMenuCmd, Command);
 
 void ShowRootMenuCmd::execute() {
     BScreen *screen = Fluxbox::instance()->mouseScreen();
@@ -364,7 +366,7 @@ void ShowRootMenuCmd::execute() {
     ::showMenu(*screen, screen->rootMenu());
 }
 
-REGISTER_COMMAND(workspacemenu, FbCommands::ShowWorkspaceMenuCmd);
+REGISTER_OBJECT(workspacemenu, FbCommands::ShowWorkspaceMenuCmd, Command);
 
 void ShowWorkspaceMenuCmd::execute() {
     BScreen *screen = Fluxbox::instance()->mouseScreen();
@@ -374,7 +376,7 @@ void ShowWorkspaceMenuCmd::execute() {
     ::showMenu(*screen, screen->workspaceMenu());
 }
 
-REGISTER_COMMAND_WITH_ARGS(setworkspacename, FbCommands::SetWorkspaceNameCmd);
+REGISTER_OBJECT_WITH_ARGS(setworkspacename, FbCommands::SetWorkspaceNameCmd, Command);
 
 SetWorkspaceNameCmd::SetWorkspaceNameCmd(const string &name, int spaceid):
     m_name(name), m_workspace(spaceid) {
@@ -403,7 +405,7 @@ void SetWorkspaceNameCmd::execute() {
     Fluxbox::instance()->save_rc();
 }
 
-REGISTER_COMMAND(setworkspacenamedialog, FbCommands::WorkspaceNameDialogCmd);
+REGISTER_OBJECT(setworkspacenamedialog, FbCommands::WorkspaceNameDialogCmd, Command);
 
 void WorkspaceNameDialogCmd::execute() {
 
@@ -416,7 +418,7 @@ void WorkspaceNameDialogCmd::execute() {
     win->show();
 }
 
-REGISTER_COMMAND(commanddialog, FbCommands::CommandDialogCmd);
+REGISTER_OBJECT(commanddialog, FbCommands::CommandDialogCmd, Command);
 
 void CommandDialogCmd::execute() {
     BScreen *screen = Fluxbox::instance()->mouseScreen();
@@ -443,7 +445,7 @@ void SetResourceValueCmd::execute() {
     Fluxbox::instance()->save_rc();
 }
 
-REGISTER_COMMAND(setresourcevaluedialog, FbCommands::SetResourceValueDialogCmd);
+REGISTER_OBJECT(setresourcevaluedialog, FbCommands::SetResourceValueDialogCmd, Command);
 
 void SetResourceValueDialogCmd::execute() {
     BScreen *screen = Fluxbox::instance()->mouseScreen();
@@ -454,7 +456,7 @@ void SetResourceValueDialogCmd::execute() {
     win->show();
 };
 
-REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(bindkey, FbCommands::BindKeyCmd);
+REGISTER_UNTRUSTED_OBJECT_WITH_ARGS(bindkey, FbCommands::BindKeyCmd, Command);
 
 BindKeyCmd::BindKeyCmd(const string &keybind):m_keybind(keybind) { }
 
@@ -502,7 +504,7 @@ FbTk::Command *DeiconifyCmd::parse(const string &command, const string &args,
     return new DeiconifyCmd(DeiconifyCmd::LASTWORKSPACE, dest);
 }
 
-REGISTER_COMMAND_PARSER(deiconify, DeiconifyCmd::parse);
+REGISTER_OBJECT_PARSER(deiconify, DeiconifyCmd::parse, Command);
 
 DeiconifyCmd::DeiconifyCmd(Mode mode,
                            Destination dest) : m_mode(mode), m_dest(dest) { }
diff --git a/src/FbTk/CommandRegistry.cc b/src/FbTk/CommandRegistry.cc
deleted file mode 100644
index fc40920..0000000
--- a/src/FbTk/CommandRegistry.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-// CommandRegistry.cc for FbTk
-// Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-// $Id: $
-
-#include "CommandRegistry.hh"
-#include "Command.hh"
-#include "StringUtil.hh"
-
-#include <iostream>
-
-namespace FbTk {
-
-CommandRegistry &CommandRegistry::instance() {
-    static CommandRegistry s_instance;
-    return s_instance;
-}
-
-
-bool CommandRegistry::registerCommand(string name,
-                                      CreateFunction createFunction) {
-    name = StringUtil::toLower(name);
-    m_commandCreators[name] = createFunction;
-    return true;
-}
-
-bool CommandRegistry::registerBoolCommand(string name,
-                                          BoolCreateFunction createFunction) {
-    name = StringUtil::toLower(name);
-    m_boolcommandCreators[name] = createFunction;
-    return true;
-}
-
-Command *CommandRegistry::parseLine(const string &line, bool trusted) const {
-    // parse args and command
-    string command, args;
-    StringUtil::getFirstWord(line, command, args);
-    StringUtil::removeFirstWhitespace(args);
-    StringUtil::removeTrailingWhitespace(args);
-
-    // now we have parsed command and args
-    command = StringUtil::toLower(command);
-    return getCommand(command, args, trusted);
-}
-
-BoolCommand *CommandRegistry::parseBoolLine(const string &line, bool trusted) const {
-    // parse args and command
-    string command, args;
-    StringUtil::getFirstWord(line, command, args);
-    StringUtil::removeFirstWhitespace(args);
-    StringUtil::removeTrailingWhitespace(args);
-
-    // now we have parsed command and args
-    command = StringUtil::toLower(command);
-    return getBoolCommand(command, args, trusted);
-}
-
-Command *CommandRegistry::getCommand(const string &name, const string &args,
-                                     bool trusted) const {
-    string lc = StringUtil::toLower(name);
-    CreatorMap::const_iterator it = m_commandCreators.find(lc.c_str());
-    if (it == m_commandCreators.end())
-        return 0;
-    else
-        return it->second(name, args, trusted);
-}
-
-BoolCommand *CommandRegistry::getBoolCommand(const string &name,
-        const string &args, bool trusted) const {
-    string lc = StringUtil::toLower(name);
-    BoolCreatorMap::const_iterator it = m_boolcommandCreators.find(lc.c_str());
-    if (it == m_boolcommandCreators.end())
-        return 0;
-    else
-        return it->second(name, args, trusted);
-}
-
-}; // end namespace FbTk
diff --git a/src/FbTk/CommandRegistry.hh b/src/FbTk/CommandRegistry.hh
deleted file mode 100644
index f3b6880..0000000
--- a/src/FbTk/CommandRegistry.hh
+++ /dev/null
@@ -1,130 +0,0 @@
-// CommandRegistry.hh for FbTk
-// Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-// $Id: $
-
-#ifndef COMMANDREGISTRY_HH
-#define COMMANDREGISTRY_HH
-
-#include <string>
-#include <map>
-
-using std::string;
-
-namespace FbTk {
-class Command;
-class BoolCommand;
-
-#define REGISTER_COMMAND_PARSER(name, parser) \
-  namespace { \
-    static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, parser); \
-  }
-
-#define REGISTER_BOOLCOMMAND_PARSER(name, parser) \
-  namespace { \
-    static const bool p_register_##name = FbTk::CommandRegistry::instance().registerBoolCommand(#name, parser); \
-  }
-
-/* Include some basic command creators */
-template <typename Cmd, typename Ret>
-Ret *CommandCreator(const string &name, const string &args, bool trusted) {
-    return new Cmd();
-}
-
-#define REGISTER_COMMAND(name, classname) \
-  namespace { \
-    static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::CommandCreator<classname, FbTk::Command>); \
-  }
-
-template <typename Cmd, typename Ret>
-Ret *CommandCreatorWithArgs(const string &name, const string &args,
-                            bool trusted) {
-    return new Cmd(args);
-}
-
-#define REGISTER_COMMAND_WITH_ARGS(name, classname) \
-  namespace { \
-    static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::CommandCreatorWithArgs<classname, FbTk::Command>); \
-  }
-
-#define REGISTER_BOOLCOMMAND_WITH_ARGS(name, classname) \
-  namespace { \
-    static const bool p_register_##name = FbTk::CommandRegistry::instance().registerBoolCommand(#name, FbTk::CommandCreatorWithArgs<classname, FbTk::BoolCommand>); \
-  }
-
-template <typename Cmd, typename Ret>
-Ret *UntrustedCommandCreator(const string &name, const string &args,
-                             bool trusted) {
-    if (!trusted) return 0;
-    return new Cmd();
-}
-
-#define REGISTER_UNTRUSTED_COMMAND(name, classname) \
-  namespace { \
-    static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::UntrustedCommandCreator<classname, FbTk::Command>); \
-  }
-
-template <typename Cmd, typename Ret>
-Ret * UntrustedCommandCreatorWithArgs(const string &name, const string &args,
-                                      bool trusted) {
-    if (!trusted) return 0;
-    return new Cmd(args);
-}
-
-#define REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(name, classname) \
-  namespace { \
-    static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::UntrustedCommandCreatorWithArgs<classname, FbTk::Command>); \
-  }
-
-/* Not built to be virtual at the moment */
-class CommandRegistry {
-public:
-    typedef Command * CreateFunction(const string &name, const string &args, bool trusted);
-    typedef BoolCommand * BoolCreateFunction(const string &name,
-                                             const string &args, bool trusted);
-    typedef std::map<string, CreateFunction *> CreatorMap;
-    typedef std::map<string, BoolCreateFunction *> BoolCreatorMap;
-
-    static CommandRegistry &instance();
-
-    Command *parseLine(const string &line, bool trusted = true) const;
-    BoolCommand *parseBoolLine(const string &line, bool trusted = true) const;
-    Command *getCommand(const string &name, const string &args, bool trusted) const;
-    BoolCommand *getBoolCommand(const string &name, const string &args,
-                                bool trusted) const;
-
-    /* Note: the ownership of this object passes to this class */
-    bool registerCommand(string name, CreateFunction createFunction);
-    bool registerBoolCommand(string name, BoolCreateFunction bcf);
-
-    const CreatorMap commandMap() const { return m_commandCreators; }
-
-private:
-    CommandRegistry() {}
-    ~CommandRegistry() {}
-
-    CreatorMap m_commandCreators;
-    BoolCreatorMap m_boolcommandCreators;
-};
-
-}; // end namespace FbTk
-
-#endif // COMMANDREGISTRY_HH
diff --git a/src/FbTk/LogicCommands.cc b/src/FbTk/LogicCommands.cc
index 1c6f238..df5f2d5 100644
--- a/src/FbTk/LogicCommands.cc
+++ b/src/FbTk/LogicCommands.cc
@@ -23,7 +23,7 @@
 
 #include "LogicCommands.hh"
 
-#include "CommandRegistry.hh"
+#include "ObjectRegistry.hh"
 #include "StringUtil.hh"
 
 using FbTk::StringUtil::removeFirstWhitespace;
@@ -47,7 +47,7 @@ M *addCommands(M *macro, const string &args, bool trusted) {
         if (err == 0)
             break;
 
-        tmp = CommandRegistry::instance().parseBoolLine(cmd, trusted);
+        tmp = ObjectRegistry<BoolCommand>::instance().parse(cmd, trusted);
         if (*tmp)
             macro->add(tmp);
     }
@@ -62,7 +62,7 @@ BoolCommand *parseLogicCommand(const string &command, const string &args,
                                bool trusted) {
     if (command == "not") {
         BoolCommand *boolcmd =
-                CommandRegistry::instance().parseBoolLine(args, trusted);
+                ObjectRegistry<BoolCommand>::instance().parse(args, trusted);
         if (!boolcmd)
             return 0;
         RefCount<BoolCommand> ref(boolcmd);
@@ -76,10 +76,10 @@ BoolCommand *parseLogicCommand(const string &command, const string &args,
     return 0;
 }
 
-REGISTER_BOOLCOMMAND_PARSER(not, parseLogicCommand);
-REGISTER_BOOLCOMMAND_PARSER(and, parseLogicCommand);
-REGISTER_BOOLCOMMAND_PARSER(or, parseLogicCommand);
-REGISTER_BOOLCOMMAND_PARSER(xor, parseLogicCommand);
+REGISTER_OBJECT_PARSER(not, parseLogicCommand, BoolCommand);
+REGISTER_OBJECT_PARSER(and, parseLogicCommand, BoolCommand);
+REGISTER_OBJECT_PARSER(or, parseLogicCommand, BoolCommand);
+REGISTER_OBJECT_PARSER(xor, parseLogicCommand, BoolCommand);
 
 }; // end anonymous namespace
 
@@ -93,7 +93,7 @@ Command *IfCommand::parse(const std::string &command, const std::string &args,
     err = StringUtil::getStringBetween(cmd, args.c_str(),
                                        '{', '}', " \t\n", true);
     if (err > 0)
-        cond = CommandRegistry::instance().parseBoolLine(cmd, trusted);
+        cond = ObjectRegistry<BoolCommand>::instance().parse(cmd, trusted);
     if (err == 0 || *cond == 0)
         return 0;
 
@@ -102,21 +102,21 @@ Command *IfCommand::parse(const std::string &command, const std::string &args,
                                        '{', '}', " \t\n", true);
     if (err == 0)
         return 0;
-    t = CommandRegistry::instance().parseLine(cmd, trusted);
+    t = ObjectRegistry<Command>::instance().parse(cmd, trusted);
 
     pos += err;
     err = StringUtil::getStringBetween(cmd, args.c_str() + pos,
                                        '{', '}', " \t\n", true);
     if (err > 0)
-        f = CommandRegistry::instance().parseLine(cmd, trusted);
+        f = ObjectRegistry<Command>::instance().parse(cmd, trusted);
     if (err == 0 || *t == 0 && *f == 0)
         return 0;
 
     return new IfCommand(cond, t, f);
 }
 
-REGISTER_COMMAND_PARSER(if, IfCommand::parse);
-REGISTER_COMMAND_PARSER(cond, IfCommand::parse);
+REGISTER_OBJECT_PARSER(if, IfCommand::parse, Command);
+REGISTER_OBJECT_PARSER(cond, IfCommand::parse, Command);
 
 void OrCommand::add(RefCount<BoolCommand> &com) {
     m_commandlist.push_back(com);
diff --git a/src/FbTk/MacroCommand.cc b/src/FbTk/MacroCommand.cc
index 20e91e4..55d403c 100644
--- a/src/FbTk/MacroCommand.cc
+++ b/src/FbTk/MacroCommand.cc
@@ -23,7 +23,7 @@
 
 #include "MacroCommand.hh"
 
-#include "CommandRegistry.hh"
+#include "ObjectRegistry.hh"
 #include "StringUtil.hh"
 
 #include <string>
@@ -47,7 +47,7 @@ M *addCommands(M *macro, const std::string &args, bool trusted) {
         if (err == 0)
             break;
         if (err > 0)
-            next = CommandRegistry::instance().parseLine(cmd, trusted);
+            next = ObjectRegistry<Command>::instance().parse(cmd, trusted);
         if (*next != 0)
             macro->add(next);
     }
@@ -68,8 +68,8 @@ Command *parseMacroCmd(const std::string &command, const std::string &args,
     return 0;
 }
 
-REGISTER_COMMAND_PARSER(macrocmd, parseMacroCmd);
-REGISTER_COMMAND_PARSER(togglecmd, parseMacroCmd);
+REGISTER_OBJECT_PARSER(macrocmd, parseMacroCmd, Command);
+REGISTER_OBJECT_PARSER(togglecmd, parseMacroCmd, Command);
 
 }; // end anonymous namespace
 
diff --git a/src/FbTk/Makefile.am b/src/FbTk/Makefile.am
index f3e928d..081bd07 100644
--- a/src/FbTk/Makefile.am
+++ b/src/FbTk/Makefile.am
@@ -16,7 +16,7 @@ imlib2_SOURCE= ImageImlib2.hh ImageImlib2.cc
 endif
 
 libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \
-	CommandRegistry.hh CommandRegistry.cc \
+	ObjectRegistry.hh \
 	FileUtil.hh FileUtil.cc \
 	EventHandler.hh EventManager.hh EventManager.cc \
 	FbWindow.hh FbWindow.cc Font.cc Font.hh FontImp.hh \
diff --git a/src/FbTk/ObjectRegistry.hh b/src/FbTk/ObjectRegistry.hh
new file mode 100644
index 0000000..bc1964c
--- /dev/null
+++ b/src/FbTk/ObjectRegistry.hh
@@ -0,0 +1,160 @@
+// ObjectRegistry.hh for FbTk
+// Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+// $Id: $
+
+#ifndef OBJECTREGISTRY_HH
+#define OBJECTREGISTRY_HH
+
+#include "StringUtil.hh"
+
+#include <string>
+#include <map>
+
+using std::string;
+
+namespace FbTk {
+
+#define REGISTER_OBJECT_PARSER(name, parser, type) \
+  namespace { \
+    static const bool p_register_##type_##name = FbTk::ObjectRegistry<type>::instance().registerObject(#name, parser); \
+  }
+
+#define REGISTER_OBJECT_PARSER_NSBASE(name, parser, space, base) \
+  namespace { \
+    static const bool p_register_##type_##name = FbTk::ObjectRegistry<space::base >::instance().registerObject(#name, parser); \
+  }
+
+/* Include some basic Object creators */
+template <typename Derived, typename Base>
+Base *ObjectCreator(const string &name, const string &args, bool trusted) {
+    return new Derived();
+}
+
+#define REGISTER_OBJECT(name, derived, base) \
+  namespace { \
+    static const bool p_register_##type_##name = FbTk::ObjectRegistry<base >::instance().registerObject(#name, FbTk::ObjectCreator<derived, base >); \
+  }
+
+#define REGISTER_OBJECT_NSBASE(name, derived, space, base) \
+  namespace { \
+    static const bool p_register_##type_##name = FbTk::ObjectRegistry<space::base >::instance().registerObject(#name, FbTk::ObjectCreator<derived, space::base >); \
+  }
+
+template <typename Derived, typename Base>
+Base *ObjectCreatorWithArgs(const string &name, const string &args,
+                            bool trusted) {
+    return new Derived(args);
+}
+
+#define REGISTER_OBJECT_WITH_ARGS(name, derived, base) \
+  namespace { \
+    static const bool p_register_##type_##name = FbTk::ObjectRegistry<base >::instance().registerObject(#name, FbTk::ObjectCreatorWithArgs<derived, base >); \
+  }
+
+#define REGISTER_OBJECT_WITH_ARGS_NSBASE(name, derived, space, base) \
+  namespace { \
+    static const bool p_register_##type_##name = FbTk::ObjectRegistry<space::base >::instance().registerObject(#name, FbTk::ObjectCreatorWithArgs<derived, space::base >); \
+  }
+
+template <typename Derived, typename Base>
+Base *UntrustedObjectCreator(const string &name, const string &args,
+                             bool trusted) {
+    if (!trusted) return 0;
+    return new Derived();
+}
+
+#define REGISTER_UNTRUSTED_OBJECT(name, derived, base) \
+  namespace { \
+    static const bool p_register_##type_##name = FbTk::ObjectRegistry<base >::instance().registerObject(#name, FbTk::UntrustedObjectCreator<derived, base >); \
+  }
+
+#define REGISTER_UNTRUSTED_OBJECT_NSBASE(name, derived, space, base) \
+  namespace { \
+    static const bool p_register_##type_##name = FbTk::ObjectRegistry<space::base >::instance().registerObject(#name, FbTk::UntrustedObjectCreator<derived, space::base >); \
+  }
+
+template <typename Derived, typename Base>
+Base * UntrustedObjectCreatorWithArgs(const string &name, const string &args,
+                                      bool trusted) {
+    if (!trusted) return 0;
+    return new Derived(args);
+}
+
+#define REGISTER_UNTRUSTED_OBJECT_WITH_ARGS(name, derived, base) \
+  namespace { \
+    static const bool p_register_##type_##name = FbTk::ObjectRegistry<base >::instance().registerObject(#name, FbTk::UntrustedObjectCreatorWithArgs<derived, base >); \
+  }
+
+#define REGISTER_UNTRUSTED_OBJECT_WITH_ARGS_NSBASE(name, derived, space, base) \
+  namespace { \
+    static const bool p_register_##type_##name = FbTk::ObjectRegistry<space::base >::instance().registerObject(#name, FbTk::UntrustedObjectCreatorWithArgs<derived, space::base >); \
+  }
+
+template <typename Base>
+class ObjectRegistry {
+public:
+    typedef Base * CreateFunction(const string &name, const string &args, bool trusted);
+    typedef std::map<string, CreateFunction *> CreatorMap;
+
+    static ObjectRegistry<Base > &instance() {
+        static ObjectRegistry<Base > s_instance;
+        return s_instance;
+    }
+
+    Base *parse(const string &name, const string &args, bool trusted = true) const {
+        string lc = StringUtil::toLower(name);
+        typename CreatorMap::const_iterator it = m_creators.find(lc.c_str());
+        if (it == m_creators.end())
+            return 0;
+        else
+            return it->second(lc, args, trusted);
+    }
+
+    Base *parse(const string &line, bool trusted = true) const {
+        // parse args and command
+        string command, args;
+        StringUtil::getFirstWord(line, command, args);
+        StringUtil::removeFirstWhitespace(args);
+        StringUtil::removeTrailingWhitespace(args);
+
+        // now we have parsed command and args
+        return parse(command, args, trusted);
+    }
+
+    bool registerObject(string name, CreateFunction createFunction) {
+        name = StringUtil::toLower(name);
+        m_creators[name] = createFunction;
+        return true;
+    }
+
+    const CreatorMap creatorMap() const { return m_creators; }
+
+private:
+    ObjectRegistry() {}
+    ~ObjectRegistry() {}
+
+    CreatorMap m_creators;
+};
+
+}; // end namespace FbTk
+
+#endif // OBJECTREGISTRY_HH
diff --git a/src/IconbarTool.cc b/src/IconbarTool.cc
index f0179d1..1e575dc 100644
--- a/src/IconbarTool.cc
+++ b/src/IconbarTool.cc
@@ -33,7 +33,7 @@
 #include "Workspace.hh"
 #include "FbMenu.hh"
 #include "BoolMenuItem.hh"
-#include "FbTk/CommandRegistry.hh"
+#include "FbTk/ObjectRegistry.hh"
 #include "WinClient.hh"
 #include "FocusControl.hh"
 #include "FbCommands.hh"
@@ -282,7 +282,7 @@ IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme,
     // setup use pixmap item to reconfig iconbar and save resource on click
     MacroCommand *save_and_reconfig = new MacroCommand();
     RefCount<Command> reconfig(new SimpleCommand<IconbarTool>(*this, &IconbarTool::renderTheme));
-    RefCount<Command> save(FbTk::CommandRegistry::instance().parseLine("saverc"));
+    RefCount<Command> save(FbTk::ObjectRegistry<Command>::instance().parse("saverc"));
     save_and_reconfig->add(reconfig);
     save_and_reconfig->add(save);
     RefCount<Command> s_and_reconfig(save_and_reconfig);
diff --git a/src/Keys.cc b/src/Keys.cc
index e102029..0be5384 100644
--- a/src/Keys.cc
+++ b/src/Keys.cc
@@ -32,7 +32,7 @@
 #include "FbTk/App.hh"
 #include "FbTk/Command.hh"
 
-#include "FbTk/CommandRegistry.hh"
+#include "FbTk/ObjectRegistry.hh"
 #include "FbTk/I18n.hh"
 
 #ifdef HAVE_CONFIG_H
@@ -395,7 +395,7 @@ bool Keys::addBinding(const string &linebuffer) {
             const char *str = FbTk::StringUtil::strcasestr(linebuffer.c_str(),
                     val[argc].c_str() + 1); // +1 to skip ':'
             if (str)
-                current_key->m_command = FbTk::CommandRegistry::instance().parseLine(str);
+                current_key->m_command = FbTk::ObjectRegistry<FbTk::Command>::instance().parse(str);
 
             if (!str || *current_key->m_command == 0 || mod) {
                 delete first_new_key;
diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc
index 0597d6c..baa49fb 100644
--- a/src/MenuCreator.cc
+++ b/src/MenuCreator.cc
@@ -26,7 +26,7 @@
 
 #include "defaults.hh"
 #include "Screen.hh"
-#include "FbTk/CommandRegistry.hh"
+#include "FbTk/ObjectRegistry.hh"
 #include "fluxbox.hh"
 #include "Window.hh"
 #include "WindowCmd.hh"
@@ -247,7 +247,7 @@ static void translateMenuItem(Parser &parse, ParseItem &pitem, FbTk::StringConve
         else
             menu.insert(str_label, submenu);
     } else if (str_key == "exit") { // exit
-        FbTk::RefCount<FbTk::Command> exit_cmd(FbTk::CommandRegistry::instance().parseLine("exit"));
+        FbTk::RefCount<FbTk::Command> exit_cmd(FbTk::ObjectRegistry<FbTk::Command>::instance().parse("exit"));
         if (str_label.empty())
             menu.insert(_FB_XTEXT(Menu, Exit, "Exit", "Exit Command"), exit_cmd);
         else
@@ -255,11 +255,11 @@ static void translateMenuItem(Parser &parse, ParseItem &pitem, FbTk::StringConve
     } else if (str_key == "exec") {
         // execute and hide menu
         using namespace FbTk;
-        RefCount<Command> exec_cmd(FbTk::CommandRegistry::instance().parseLine("exec " + str_cmd));
+        RefCount<Command> exec_cmd(FbTk::ObjectRegistry<FbTk::Command>::instance().parse("exec " + str_cmd));
         menu.insert(str_label, exec_cmd);
     } else if (str_key == "macrocmd") {
         using namespace FbTk;
-        RefCount<Command> macro_cmd(FbTk::CommandRegistry::instance().parseLine("macrocmd " + str_cmd));
+        RefCount<Command> macro_cmd(FbTk::ObjectRegistry<FbTk::Command>::instance().parse("macrocmd " + str_cmd));
         menu.insert(str_label, macro_cmd);
     } else if (str_key == "style") {	// style
         menu.insert(new StyleMenuItem(str_label, str_cmd));
@@ -354,7 +354,7 @@ static void translateMenuItem(Parser &parse, ParseItem &pitem, FbTk::StringConve
     else { // ok, if we didn't find any special menu item we try with command parser
         // we need to attach command with arguments so command parser can parse it
         string line = str_key + " " + str_cmd;
-        FbTk::RefCount<FbTk::Command> command(FbTk::CommandRegistry::instance().parseLine(line));
+        FbTk::RefCount<FbTk::Command> command(FbTk::ObjectRegistry<FbTk::Command>::instance().parse(line));
         if (*command != 0) {
             // special NLS default labels
             if (str_label.empty()) {
diff --git a/src/Screen.cc b/src/Screen.cc
index 1651824..d27f8c4 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -60,7 +60,7 @@
 #include "WinClient.hh"
 #include "FbWinFrame.hh"
 #include "Strut.hh"
-#include "FbTk/CommandRegistry.hh"
+#include "FbTk/ObjectRegistry.hh"
 #include "AtomHandler.hh"
 #include "HeadArea.hh"
 #include "FbCommands.hh"
@@ -815,7 +815,7 @@ void BScreen::propertyNotify(Atom atom) {
                     &ret_bytes_after, (unsigned char **)&str);
             }
 
-            FbTk::RefCount<FbTk::Command> cmd(FbTk::CommandRegistry::instance().parseLine(str, false));
+            FbTk::RefCount<FbTk::Command> cmd(FbTk::ObjectRegistry<FbTk::Command>::instance().parse(str, false));
             if (cmd.get())
                 cmd->execute();
             XFree(str);
@@ -1531,9 +1531,9 @@ void BScreen::initMenu() {
     if (m_rootmenu.get() == 0) {
         _FB_USES_NLS;
         m_rootmenu.reset(createMenu(_FB_XTEXT(Menu, DefaultRootMenu, "Fluxbox default menu", "Title of fallback root menu")));
-        FbTk::RefCount<FbTk::Command> restart_fb(FbTk::CommandRegistry::instance().parseLine("restart"));
-        FbTk::RefCount<FbTk::Command> exit_fb(FbTk::CommandRegistry::instance().parseLine("exit"));
-        FbTk::RefCount<FbTk::Command> execute_xterm(FbTk::CommandRegistry::instance().parseLine("exec xterm"));
+        FbTk::RefCount<FbTk::Command> restart_fb(FbTk::ObjectRegistry<FbTk::Command>::instance().parse("restart"));
+        FbTk::RefCount<FbTk::Command> exit_fb(FbTk::ObjectRegistry<FbTk::Command>::instance().parse("exit"));
+        FbTk::RefCount<FbTk::Command> execute_xterm(FbTk::ObjectRegistry<FbTk::Command>::instance().parse("exec xterm"));
         m_rootmenu->setInternalMenu();
         m_rootmenu->insert("xterm", execute_xterm);
         m_rootmenu->insert(_FB_XTEXT(Menu, Restart, "Restart", "Restart command"),
@@ -1578,7 +1578,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
     FbTk::RefCount<FbTk::Command> saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(
                                                  *Fluxbox::instance(),
                                                  &Fluxbox::save_rc));
-    FbTk::RefCount<FbTk::Command> reconf_cmd(FbTk::CommandRegistry::instance().parseLine("reconfigure"));
+    FbTk::RefCount<FbTk::Command> reconf_cmd(FbTk::ObjectRegistry<FbTk::Command>::instance().parse("reconfigure"));
 
     FbTk::RefCount<FbTk::Command> reconftabs_cmd(new FbTk::SimpleCommand<BScreen>(
                                                  *this,
diff --git a/src/ToolFactory.cc b/src/ToolFactory.cc
index c54dd19..35bdf75 100644
--- a/src/ToolFactory.cc
+++ b/src/ToolFactory.cc
@@ -36,7 +36,7 @@
 #include "WorkspaceNameTheme.hh"
 #include "ButtonTheme.hh"
 
-#include "FbTk/CommandRegistry.hh"
+#include "FbTk/ObjectRegistry.hh"
 #include "Screen.hh"
 #include "Toolbar.hh"
 #include "fluxbox.hh"
@@ -107,7 +107,7 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
     } else if (name == "nextworkspace" || 
                name == "prevworkspace") {
 
-        FbTk::RefCount<FbTk::Command> cmd(FbTk::CommandRegistry::instance().parseLine(name));
+        FbTk::RefCount<FbTk::Command> cmd(FbTk::ObjectRegistry<FbTk::Command>::instance().parse(name));
         if (*cmd == 0) // we need a command
             return 0;
 
@@ -127,7 +127,7 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
     } else if (name == "nextwindow" || 
                name == "prevwindow") {
 
-        FbTk::RefCount<FbTk::Command> cmd(FbTk::CommandRegistry::instance().parseLine(name));
+        FbTk::RefCount<FbTk::Command> cmd(FbTk::ObjectRegistry<FbTk::Command>::instance().parse(name));
         if (*cmd == 0) // we need a command
             return 0;
 
diff --git a/src/Toolbar.cc b/src/Toolbar.cc
index 3e446d8..2e3afd5 100644
--- a/src/Toolbar.cc
+++ b/src/Toolbar.cc
@@ -44,7 +44,7 @@
 #endif // XINERAMA
 
 #include "Strut.hh"
-#include "FbTk/CommandRegistry.hh"
+#include "FbTk/ObjectRegistry.hh"
 #include "Layer.hh"
 
 #include "FbTk/I18n.hh"
@@ -823,7 +823,7 @@ void Toolbar::setupMenus(bool skip_new_placement) {
                               "Toolbar", "Title of Toolbar menu"));
 
     RefCommand reconfig_toolbar(new ToolbarCommand(*this, &Toolbar::reconfigure));
-    RefCommand save_resources(FbTk::CommandRegistry::instance().parseLine("saverc"));
+    RefCommand save_resources(FbTk::ObjectRegistry<Command>::instance().parse("saverc"));
     MacroCommand *toolbar_menuitem_macro = new MacroCommand();
     toolbar_menuitem_macro->add(reconfig_toolbar);
     toolbar_menuitem_macro->add(save_resources);
diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc
index 5498b38..2d2964e 100644
--- a/src/WorkspaceCmd.cc
+++ b/src/WorkspaceCmd.cc
@@ -33,7 +33,7 @@
 #include "WindowCmd.hh"
 
 #include "FbTk/KeyUtil.hh"
-#include "FbTk/CommandRegistry.hh"
+#include "FbTk/ObjectRegistry.hh"
 #include "FbTk/stringstream.hh"
 
 #ifdef HAVE_CMATH
@@ -45,6 +45,8 @@
 #include <functional>
 
 using std::string;
+using FbTk::Command;
+using FbTk::BoolCommand;
 
 void WindowListCmd::execute() {
     if (m_pat.error()) {
@@ -72,8 +74,9 @@ void WindowListCmd::execute() {
 
 FbTk::BoolCommand *SomeCmd::parse(const string &command, const string &args,
                                   bool trusted) {
-    BoolCommand *boolcmd =
-            FbTk::CommandRegistry::instance().parseBoolLine(args, trusted);
+    FbTk::BoolCommand *boolcmd =
+            FbTk::ObjectRegistry<FbTk::BoolCommand>::instance().parse(args,
+                                                                      trusted);
     if (!boolcmd)
         return 0;
     if (command == "some")
@@ -81,8 +84,8 @@ FbTk::BoolCommand *SomeCmd::parse(const string &command, const string &args,
     return new EveryCmd(FbTk::RefCount<FbTk::BoolCommand>(boolcmd));
 }
 
-REGISTER_BOOLCOMMAND_PARSER(some, SomeCmd::parse);
-REGISTER_BOOLCOMMAND_PARSER(every, SomeCmd::parse);
+REGISTER_OBJECT_PARSER(some, SomeCmd::parse, BoolCommand);
+REGISTER_OBJECT_PARSER(every, SomeCmd::parse, BoolCommand);
 
 bool SomeCmd::bool_execute() {
     BScreen *screen = Fluxbox::instance()->keyScreen();
@@ -149,11 +152,11 @@ FbTk::Command *parseWindowList(const string &command,
     return 0;
 }
 
-REGISTER_COMMAND_PARSER(attach, parseWindowList);
-REGISTER_COMMAND_PARSER(nextwindow, parseWindowList);
-REGISTER_COMMAND_PARSER(nextgroup, parseWindowList);
-REGISTER_COMMAND_PARSER(prevwindow, parseWindowList);
-REGISTER_COMMAND_PARSER(prevgroup, parseWindowList);
+REGISTER_OBJECT_PARSER(attach, parseWindowList, Command);
+REGISTER_OBJECT_PARSER(nextwindow, parseWindowList, Command);
+REGISTER_OBJECT_PARSER(nextgroup, parseWindowList, Command);
+REGISTER_OBJECT_PARSER(prevwindow, parseWindowList, Command);
+REGISTER_OBJECT_PARSER(prevgroup, parseWindowList, Command);
 
 }; // end anonymous namespace
 
@@ -202,7 +205,7 @@ FbTk::Command *GoToWindowCmd::parse(const string &command,
     return new GoToWindowCmd(num, opts, pat);
 }
 
-REGISTER_COMMAND_PARSER(gotowindow, GoToWindowCmd::parse);
+REGISTER_OBJECT_PARSER(gotowindow, GoToWindowCmd::parse, Command);
 
 void GoToWindowCmd::execute() {
     BScreen *screen = Fluxbox::instance()->keyScreen();
@@ -226,10 +229,10 @@ FbTk::Command *DirFocusCmd::parse(const string &command,
     return 0;
 }
 
-REGISTER_COMMAND_PARSER(focusup, DirFocusCmd::parse);
-REGISTER_COMMAND_PARSER(focusdown, DirFocusCmd::parse);
-REGISTER_COMMAND_PARSER(focusleft, DirFocusCmd::parse);
-REGISTER_COMMAND_PARSER(focusright, DirFocusCmd::parse);
+REGISTER_OBJECT_PARSER(focusup, DirFocusCmd::parse, Command);
+REGISTER_OBJECT_PARSER(focusdown, DirFocusCmd::parse, Command);
+REGISTER_OBJECT_PARSER(focusleft, DirFocusCmd::parse, Command);
+REGISTER_OBJECT_PARSER(focusright, DirFocusCmd::parse, Command);
 
 void DirFocusCmd::execute() {
     BScreen *screen = Fluxbox::instance()->keyScreen();
@@ -241,7 +244,7 @@ void DirFocusCmd::execute() {
         screen->focusControl().dirFocus(*win, m_dir);
 }
 
-REGISTER_COMMAND(addworkspace, AddWorkspaceCmd);
+REGISTER_OBJECT(addworkspace, AddWorkspaceCmd, Command);
 
 void AddWorkspaceCmd::execute() {
     BScreen *screen = Fluxbox::instance()->mouseScreen();
@@ -249,7 +252,7 @@ void AddWorkspaceCmd::execute() {
         screen->addWorkspace();
 }
 
-REGISTER_COMMAND(removelastworkspace, RemoveLastWorkspaceCmd);
+REGISTER_OBJECT(removelastworkspace, RemoveLastWorkspaceCmd, Command);
 
 void RemoveLastWorkspaceCmd::execute() {
     BScreen *screen = Fluxbox::instance()->mouseScreen();
@@ -278,11 +281,11 @@ FbTk::Command *parseIntCmd(const string &command, const string &args,
     return 0;
 }
 
-REGISTER_COMMAND_PARSER(nextworkspace, parseIntCmd);
-REGISTER_COMMAND_PARSER(prevworkspace, parseIntCmd);
-REGISTER_COMMAND_PARSER(rightworkspace, parseIntCmd);
-REGISTER_COMMAND_PARSER(leftworkspace, parseIntCmd);
-REGISTER_COMMAND_PARSER(workspace, parseIntCmd);
+REGISTER_OBJECT_PARSER(nextworkspace, parseIntCmd, Command);
+REGISTER_OBJECT_PARSER(prevworkspace, parseIntCmd, Command);
+REGISTER_OBJECT_PARSER(rightworkspace, parseIntCmd, Command);
+REGISTER_OBJECT_PARSER(leftworkspace, parseIntCmd, Command);
+REGISTER_OBJECT_PARSER(workspace, parseIntCmd, Command);
 
 }; // end anonymous namespace
 
@@ -325,7 +328,7 @@ void JumpToWorkspaceCmd::execute() {
     }
 }
 
-REGISTER_COMMAND(arrangewindows, ArrangeWindowsCmd);
+REGISTER_OBJECT(arrangewindows, ArrangeWindowsCmd, Command);
 
 /**
   try to arrange the windows on the current workspace in a 'clever' way.
@@ -451,7 +454,7 @@ void ArrangeWindowsCmd::execute() {
     }
 }
 
-REGISTER_COMMAND(showdesktop, ShowDesktopCmd);
+REGISTER_OBJECT(showdesktop, ShowDesktopCmd, Command);
 
 void ShowDesktopCmd::execute() {
     BScreen *screen = Fluxbox::instance()->mouseScreen();
@@ -467,7 +470,7 @@ void ShowDesktopCmd::execute() {
     }
 }
 
-REGISTER_COMMAND(closeallwindows, CloseAllWindowsCmd);
+REGISTER_OBJECT(closeallwindows, CloseAllWindowsCmd, Command);
 
 void CloseAllWindowsCmd::execute() {
     BScreen *screen = Fluxbox::instance()->mouseScreen();
diff --git a/src/WorkspaceMenu.cc b/src/WorkspaceMenu.cc
index 23d4007..60d2e56 100644
--- a/src/WorkspaceMenu.cc
+++ b/src/WorkspaceMenu.cc
@@ -27,7 +27,7 @@
 #include "Workspace.hh"
 #include "WorkspaceCmd.hh"
 #include "MenuCreator.hh"
-#include "FbTk/CommandRegistry.hh"
+#include "FbTk/ObjectRegistry.hh"
 #include "FbCommands.hh"
 #include "Layer.hh"
 
@@ -147,7 +147,7 @@ void WorkspaceMenu::init(BScreen &screen) {
     remove_workspace_macro->add(saverc_cmd);
     RefCount<Command> remove_last_cmd(remove_workspace_macro);
 
-    RefCount<Command> start_edit(FbTk::CommandRegistry::instance().parseLine("setworkspacenamedialog"));
+    RefCount<Command> start_edit(FbTk::ObjectRegistry<Command>::instance().parse("setworkspacenamedialog"));
 
     insert(new FbTk::MenuSeparator());
     insert(_FB_XTEXT(Workspace, NewWorkspace, "New Workspace", "Add a new workspace"), 
-- 
cgit v0.11.2