This adds a command to the keys file named `MenuCommand'. It allows a user to open a menu containing open programs on the current workspace, from which the user may select a window, and then runs a command on that window. For example: Mod4 m :MenuCommand Maximize If the command is left blank, the window gains focus. At present, the other possible commands are: iconify, maximize, maximizevertical, maximizehorizontal, raise, raiselayer, lower, lowerlayer, close, shade, stick, toggledecor, windowmenu Index: src/FbCommands.cc =================================================================== --- src/FbCommands.cc (revision 4554) +++ src/FbCommands.cc (working copy) @@ -21,6 +21,7 @@ // $Id$ +#include "CommandParser.hh" #include "FbCommands.hh" #include "fluxbox.hh" #include "Screen.hh" @@ -265,8 +266,18 @@ ::showMenu(*screen, screen->workspaceMenu()); } +MenuCommandCmd::MenuCommandCmd(const std::string &cmd): + m_cmd(CommandParser::instance().parseLine(cmd)) { } +void MenuCommandCmd::execute() { + BScreen *screen = Fluxbox::instance()->mouseScreen(); + if (screen == 0) + return; + screen->setWorkspaceMenuCmd(m_cmd); + ::showMenu(*screen, screen->currentWorkspace()->menu()); +} + SetWorkspaceNameCmd::SetWorkspaceNameCmd(const std::string &name, int spaceid): m_name(name), m_workspace(spaceid) { } Index: src/WorkspaceMenu.hh =================================================================== --- src/WorkspaceMenu.hh (revision 4554) +++ src/WorkspaceMenu.hh (working copy) @@ -33,8 +33,11 @@ explicit WorkspaceMenu(BScreen &screen); virtual ~WorkspaceMenu() { } void update(FbTk::Subject *subj); + void show(); private: void init(BScreen &screen); + BScreen &m_screen; + FbTk::RefCount m_cmd; }; #endif // WORKSPACEMENU_HH Index: src/CurrentWindowCmd.hh =================================================================== --- src/CurrentWindowCmd.hh (revision 4554) +++ src/CurrentWindowCmd.hh (working copy) @@ -37,6 +37,7 @@ typedef void (FluxboxWindow::* Action)(); explicit CurrentWindowCmd(Action action); void execute(); + void execute(FluxboxWindow *win); private: Action m_action; }; Index: src/WorkspaceMenu.cc =================================================================== --- src/WorkspaceMenu.cc (revision 4554) +++ src/WorkspaceMenu.cc (working copy) @@ -57,7 +57,8 @@ WorkspaceMenu::WorkspaceMenu(BScreen &screen): FbMenu(screen.menuTheme(), screen.imageControl(), - *screen.layerManager().getLayer(Layer::MENU)) { + *screen.layerManager().getLayer(Layer::MENU)), + m_screen(screen), m_cmd(FbTk::RefCount(NULL)) { init(screen); @@ -106,6 +107,11 @@ } } +void WorkspaceMenu::show() { + m_screen.setWorkspaceMenuCmd(m_cmd); + FbTk::Menu::show(); +} + void WorkspaceMenu::init(BScreen &screen) { screen.currentWorkspaceSig().attach(this); screen.workspaceCountSig().attach(this); Index: src/FbTk/Menu.cc =================================================================== --- src/FbTk/Menu.cc (revision 4554) +++ src/FbTk/Menu.cc (working copy) @@ -598,7 +598,8 @@ if (validIndex(m_which_sub)) { MenuItem *tmp = menuitems[m_which_sub]; - tmp->submenu()->internal_hide(); + if (tmp->submenu()) + tmp->submenu()->internal_hide(); } // if we have an active index we need to redraw it Index: src/FbCommandFactory.cc =================================================================== --- src/FbCommandFactory.cc (revision 4554) +++ src/FbCommandFactory.cc (working copy) @@ -90,6 +90,7 @@ "maximizewindow", "minimize", "minimizewindow", + "menucommand", "moveto", "move", "movedown", @@ -408,6 +409,8 @@ return new ShowRootMenuCmd(); else if (command == "workspacemenu") return new ShowWorkspaceMenuCmd(); + else if (command == "menucommand") + return new MenuCommandCmd(arguments); else if (command == "setworkspacename") { if (arguments.empty()) return new SetWorkspaceNameCmd("empty"); Index: src/FbCommands.hh =================================================================== --- src/FbCommands.hh (revision 4554) +++ src/FbCommands.hh (working copy) @@ -27,6 +27,7 @@ #define FBCOMMANDS_HH #include "Command.hh" +#include "RefCount.hh" #include @@ -123,6 +124,14 @@ void execute(); }; +class MenuCommandCmd: public FbTk::Command { +public: + MenuCommandCmd(const std::string &cmd); + void execute(); +private: + FbTk::RefCount m_cmd; +}; + class SetWorkspaceNameCmd: public FbTk::Command { public: SetWorkspaceNameCmd(const std::string &name, int spaceid = -1); Index: src/Workspace.cc =================================================================== --- src/Workspace.cc (revision 4555) +++ src/Workspace.cc (working copy) @@ -32,6 +32,7 @@ #include "FbWinFrame.hh" #include "WindowCmd.hh" #include "FocusControl.hh" +#include "CurrentWindowCmd.hh" #include "PlacementStrategy.hh" #include "Layer.hh" @@ -87,23 +88,23 @@ class ClientMenuItem:public FbTk::MenuItem { public: ClientMenuItem(WinClient &client): - FbTk::MenuItem(client.title().c_str(), &client.screen().windowMenu()), + FbTk::MenuItem(client.title().c_str()), m_client(client) { } - FbTk::Menu *submenu() { return &m_client.screen().windowMenu(); } - const FbTk::Menu *submenu() const { return &m_client.screen().windowMenu(); } - void showSubmenu() { - WindowCmd::setWindow(m_client.fbwindow()); - FbTk::MenuItem::showSubmenu(); - } - void click(int button, int time) { if (m_client.fbwindow() == 0) return; FluxboxWindow &win = *m_client.fbwindow(); + m_client.screen().currentWorkspace()->menu().hide(); + FbTk::Command *action = m_client.screen().workspaceMenuCmd().get(); + if (action && typeid(*action) == typeid(CurrentWindowCmd)) { + static_cast(action)->execute(&win); + return; + } + if (win.screen().currentWorkspaceID() != win.workspaceNumber() && !win.isStuck()) { win.menu().hide(); Index: src/CurrentWindowCmd.cc =================================================================== --- src/CurrentWindowCmd.cc (revision 4554) +++ src/CurrentWindowCmd.cc (working copy) @@ -39,6 +39,10 @@ (win->*m_action)(); } +void CurrentWindowCmd::execute(FluxboxWindow *win) { + if (win) + (win->*m_action)(); +} void KillWindowCmd::real_execute() { winclient().sendClose(true); Index: src/Screen.hh =================================================================== --- src/Screen.hh (revision 4554) +++ src/Screen.hh (working copy) @@ -156,6 +156,9 @@ const FbTk::Menu &workspaceMenu() const { return *m_workspacemenu.get(); } FbTk::Menu &workspaceMenu() { return *m_workspacemenu.get(); } + FbTk::RefCount &workspaceMenuCmd() { return m_ws_menu_cmd; } + void setWorkspaceMenuCmd(FbTk::RefCount &cmd) { m_ws_menu_cmd = cmd; } + const FocusControl &focusControl() const { return *m_focus_control; } FocusControl &focusControl() { return *m_focus_control; } @@ -404,6 +407,8 @@ std::auto_ptr m_image_control; std::auto_ptr m_configmenu, m_rootmenu, m_workspacemenu, m_windowmenu; + FbTk::RefCount m_ws_menu_cmd; + ExtraMenus m_extramenus; typedef std::list Rootmenus;