From 5373f6d840abaa49685c15fee2f411e77472a7da Mon Sep 17 00:00:00 2001 From: fluxgen Date: Thu, 23 Jun 2005 03:07:25 +0000 Subject: moved window menu from FluxboxWindow to BScreen --- src/LayerMenu.hh | 75 +++++++------------------------- src/MenuCreator.cc | 122 ++++++++++++++++++++++++++++++++++++----------------- src/MenuCreator.hh | 7 +-- src/Remember.cc | 85 ++++++++++++++++++++++--------------- src/Screen.cc | 48 ++++++++++++++++++++- src/Screen.hh | 16 ++++++- src/SendToMenu.cc | 60 ++++++++++++-------------- src/SendToMenu.hh | 7 ++- src/Slit.cc | 18 ++++---- src/Slit.hh | 19 ++++++--- src/ToggleMenu.hh | 2 +- src/Toolbar.cc | 2 +- src/Toolbar.hh | 13 +++--- src/Window.cc | 80 +++++++---------------------------- src/Window.hh | 21 +-------- src/Workspace.cc | 11 ++++- 16 files changed, 303 insertions(+), 283 deletions(-) diff --git a/src/LayerMenu.hh b/src/LayerMenu.hh index e6a3dc6..e22ba30 100644 --- a/src/LayerMenu.hh +++ b/src/LayerMenu.hh @@ -25,91 +25,46 @@ #ifndef LAYERMENU_HH #define LAYERMENU_HH -#include "MenuItem.hh" + #include "ToggleMenu.hh" -#include "RefCount.hh" -#include "SimpleCommand.hh" -#include "I18n.hh" -#include "fluxbox.hh" +#include "FbTk/MenuItem.hh" + +class LayerObject { +public: + virtual void moveToLayer(int layer_number) = 0; + virtual int layerNumber() const = 0; +}; -// provides a generic way for giving an object a layer menu /// this class holds the layermenu items -template class LayerMenuItem : public FbTk::MenuItem { public: - LayerMenuItem(const char *label, ItemType *object, int layernum, + LayerMenuItem(const char *label, LayerObject *object, int layernum, FbTk::RefCount &cmd): - FbTk::MenuItem(label,cmd), m_object(object), m_layernum(layernum) {} - LayerMenuItem(const char *label, ItemType *object, int layernum): + FbTk::MenuItem(label, cmd), m_object(object), m_layernum(layernum) {} + + LayerMenuItem(const char *label, LayerObject *object, int layernum): FbTk::MenuItem(label), m_object(object), m_layernum(layernum) {} - bool isEnabled() const { return m_object->layerItem().getLayerNum() != m_layernum; } + bool isEnabled() const { return m_object->layerNumber() != m_layernum; } void click(int button, int time) { m_object->moveToLayer(m_layernum); FbTk::MenuItem::click(button, time); } private: - ItemType *m_object; + LayerObject *m_object; int m_layernum; }; /// Create a layer menu inside from the given menu -template class LayerMenu : public ToggleMenu { public: LayerMenu(MenuTheme &tm, FbTk::ImageControl &imgctrl, - FbTk::XLayer &layer, ItemType *item, bool save_rc); - + FbTk::XLayer &layer, LayerObject *item, bool save_rc); -private: - ItemType *m_object; }; - -template -LayerMenu::LayerMenu(MenuTheme &tm, FbTk::ImageControl &imgctrl, - FbTk::XLayer &layer, ItemType *item, bool save_rc): - ToggleMenu(tm, imgctrl, layer), - m_object(item) -{ - _FB_USES_NLS; - - Fluxbox *fluxbox = Fluxbox::instance(); - - struct { - int set; - int base; - const char *default_str; - int layernum; - } layer_menuitems[] = { - //TODO: nls - {0, 0, _FBTEXT(Layer, AboveDock, "Above Dock", "Layer above dock"), fluxbox->getAboveDockLayer()}, - {0, 0, _FBTEXT(Layer, Dock, "Dock", "Layer dock"), fluxbox->getDockLayer()}, - {0, 0, _FBTEXT(Layer, Top, "Top", "Layer top"), fluxbox->getTopLayer()}, - {0, 0, _FBTEXT(Layer, Normal, "Normal", "Layer normal"), fluxbox->getNormalLayer()}, - {0, 0, _FBTEXT(Layer, Bottom, "Bottom", "Layer bottom"), fluxbox->getBottomLayer()}, - {0, 0, _FBTEXT(Layer, Desktop, "Desktop", "Layer desktop"), fluxbox->getDesktopLayer()}, - }; - - FbTk::RefCount saverc_cmd(new FbTk::SimpleCommand( - *Fluxbox::instance(), - &Fluxbox::save_rc)); - - for (size_t i=0; i < 6; ++i) { - // TODO: fetch nls string - if (save_rc) { - insert(new LayerMenuItem(layer_menuitems[i].default_str, - m_object, layer_menuitems[i].layernum, saverc_cmd)); - } else { - insert(new LayerMenuItem(layer_menuitems[i].default_str, - m_object, layer_menuitems[i].layernum)); - } - } - updateMenu(); -} - #endif // LAYERMENU_HH diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc index 2cf281f..0bbd14f 100644 --- a/src/MenuCreator.cc +++ b/src/MenuCreator.cc @@ -29,6 +29,7 @@ #include "fluxbox.hh" #include "CommandParser.hh" #include "Window.hh" +#include "WindowCmd.hh" #include "FbMenu.hh" #include "IconMenu.hh" @@ -53,13 +54,8 @@ #include using namespace std; -template <> -void LayerMenuItem::click(int button, int time) { - m_object->moveToLayer(m_layernum); -} - static void createStyleMenu(FbTk::Menu &parent, const std::string &label, - const std::string &directory) { + const std::string &directory) { // perform shell style ~ home directory expansion string stylesdir(FbTk::StringUtil::expandFilename(directory)); @@ -326,19 +322,19 @@ static void translateMenuItem(Parser &parse, ParseItem &pitem) { } -static void parseWindowMenu(Parser &parse, FbTk::Menu &menu, FluxboxWindow &win) { +static void parseWindowMenu(Parser &parse, FbTk::Menu &menu) { ParseItem pitem(&menu); while (!parse.eof()) { pitem.load(parse); - if (MenuCreator::createWindowMenuItem(pitem.key(), pitem.label(), menu, win)) + if (MenuCreator::createWindowMenuItem(pitem.key(), pitem.label(), menu)) continue; if (pitem.key() == "end") { return; } else if (pitem.key() == "submenu") { FbTk::Menu *submenu = MenuCreator::createMenu(pitem.label(), menu.screenNumber()); - parseWindowMenu(parse, *submenu, win); + parseWindowMenu(parse, *submenu); submenu->updateMenu(); menu.insert(pitem.label().c_str(), submenu); @@ -416,9 +412,9 @@ bool MenuCreator::createFromFile(const std::string &filename, } -bool MenuCreator::createFromFile(const std::string &filename, - FbTk::Menu &inject_into, - FluxboxWindow &win, bool require_begin) { +bool MenuCreator::createWindowMenuFromFile(const std::string &filename, + FbTk::Menu &inject_into, + bool require_begin) { std::string real_filename = FbTk::StringUtil::expandFilename(filename); FbMenuParser parser(real_filename); if (!parser.isLoaded()) @@ -429,7 +425,7 @@ bool MenuCreator::createFromFile(const std::string &filename, if (require_begin && !getStart(parser, label)) return false; - parseWindowMenu(parser, inject_into, win); + parseWindowMenu(parser, inject_into); return true; } @@ -442,26 +438,56 @@ FbTk::Menu *MenuCreator::createMenuType(const std::string &type, int screen_num) return new IconMenu(*screen); } else if (type == "workspacemenu") { return new WorkspaceMenu(*screen); + } else if (type == "windowmenu") { + FbTk::Menu *menu = screen->createMenu(""); + + menu->removeAll(); // clear old items + menu->disableTitle(); // not titlebar + if (screen->windowMenuFilename().empty() || + ! createWindowMenuFromFile(screen->windowMenuFilename(), *menu, true)) { + char default_menu[][11] = { + "shade", + "stick", + "maximize", + "iconify", + "raise", + "lower", + "sendto", + "layer", + "extramenus", + "separator", + "close", + 0 + }; + for (int i=0; i < sizeof(default_menu); ++i) + createWindowMenuItem(default_menu[i], "", *menu); + } + menu->reconfigure(); // update graphics + return menu; } + return 0; } bool MenuCreator::createWindowMenuItem(const std::string &type, const std::string &label, - FbTk::Menu &menu, - FluxboxWindow &win) { + FbTk::Menu &menu) { typedef FbTk::RefCount RefCmd; - typedef FbTk::SimpleCommand WindowCmd; _FB_USES_NLS; if (type == "shade") { - RefCmd shade_cmd(new WindowCmd(win, &FluxboxWindow::shade)); + RefCmd shade_cmd(new WindowCmd(&FluxboxWindow::shade)); menu.insert(label.empty()?_FBTEXT(Windowmenu, Shade, "Shade", "Shade the window"):label.c_str(), shade_cmd); } else if (type == "maximize") { - RefCmd maximize_cmd(new WindowCmd(win, &FluxboxWindow::maximizeFull)); - RefCmd maximize_vert_cmd(new WindowCmd(win, &FluxboxWindow::maximizeVertical)); - RefCmd maximize_horiz_cmd(new WindowCmd(win, &FluxboxWindow::maximizeHorizontal)); - FbTk::MultiButtonMenuItem *maximize_item = new FbTk::MultiButtonMenuItem(3, label.empty()?_FBTEXT(Windowmenu, Maximize, "Maximize", "Maximize the window"):label.c_str()); + RefCmd maximize_cmd(new WindowCmd(&FluxboxWindow::maximizeFull)); + RefCmd maximize_vert_cmd(new WindowCmd(&FluxboxWindow::maximizeVertical)); + RefCmd maximize_horiz_cmd(new WindowCmd(&FluxboxWindow::maximizeHorizontal)); + FbTk::MultiButtonMenuItem *maximize_item = + new FbTk::MultiButtonMenuItem(3, + label.empty()? + _FBTEXT(Windowmenu, Maximize, + "Maximize", "Maximize the window"): + label.c_str()); // create maximize item with: // button1: Maximize normal // button2: Maximize Vertical @@ -471,43 +497,61 @@ bool MenuCreator::createWindowMenuItem(const std::string &type, maximize_item->setCommand(3, maximize_horiz_cmd); menu.insert(maximize_item); } else if (type == "iconify") { - RefCmd iconify_cmd(new WindowCmd(win, &FluxboxWindow::iconify)); + RefCmd iconify_cmd(new WindowCmd(&FluxboxWindow::iconify)); menu.insert(label.empty()?_FBTEXT(Windowmenu, Iconify, "Iconify", "Iconify the window"):label.c_str(), iconify_cmd); } else if (type == "close") { - RefCmd close_cmd(new WindowCmd(win, &FluxboxWindow::close)); + RefCmd close_cmd(new WindowCmd(&FluxboxWindow::close)); menu.insert(label.empty()?_FBTEXT(Windowmenu, Close, "Close", "Close the window"):label.c_str(), close_cmd); } else if (type == "kill" || type == "killwindow") { - RefCmd kill_cmd(new WindowCmd(win, &FluxboxWindow::kill)); + RefCmd kill_cmd(new WindowCmd(&FluxboxWindow::kill)); menu.insert(label.empty()?_FBTEXT(Windowmenu, Kill, "Kill", "Kill the window"):label.c_str(), kill_cmd); } else if (type == "lower") { - RefCmd lower_cmd(new WindowCmd(win, &FluxboxWindow::lower)); + RefCmd lower_cmd(new WindowCmd(&FluxboxWindow::lower)); menu.insert(label.empty()?_FBTEXT(Windowmenu, Lower, "Lower", "Lower the window"):label.c_str(), lower_cmd); } else if (type == "raise") { - RefCmd raise_cmd(new WindowCmd(win, &FluxboxWindow::raise)); + RefCmd raise_cmd(new WindowCmd(&FluxboxWindow::raise)); menu.insert(label.empty()?_FBTEXT(Windowmenu, Raise, "Raise", "Raise the window"):label.c_str(), raise_cmd); } else if (type == "stick") { - RefCmd stick_cmd(new WindowCmd(win, &FluxboxWindow::stick)); + RefCmd stick_cmd(new WindowCmd(&FluxboxWindow::stick)); menu.insert(label.empty()?_FBTEXT(Windowmenu, Stick, "Stick", "Stick the window"):label.c_str(), stick_cmd); - } else if (type == "extramenus") { - FluxboxWindow::ExtraMenus::iterator it = win.extraMenus().begin(); - FluxboxWindow::ExtraMenus::iterator it_end = win.extraMenus().end(); + } + else if (type == "extramenus") { + BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber()); + BScreen::ExtraMenus::iterator it = screen->extraWindowMenus().begin(); + BScreen::ExtraMenus::iterator it_end = screen->extraWindowMenus().end(); for (; it != it_end; ++it) { it->second->disableTitle(); menu.insert(it->first, it->second); } - + } else if (type == "sendto") { - menu.insert(label.empty()?_FBTEXT(Windowmenu, SendTo, "Send To...", "Send to menu item name"):label.c_str(), new SendToMenu(win)); - } else if (type == "layer") { + menu.insert(label.empty() ? _FBTEXT(Windowmenu, SendTo, "Send To...", "Send to menu item name"): + label.c_str(), new SendToMenu(*Fluxbox::instance()->findScreen(menu.screenNumber()))); + }else if (type == "layer") { BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber()); if (screen == 0) return false; - FbTk::Menu *submenu = new LayerMenu(screen->menuTheme(), - screen->imageControl(), - *screen->layerManager(). - getLayer(Fluxbox::instance()->getMenuLayer()), - &win, - false); + + class MenuContext: public LayerObject { + public: + void moveToLayer(int layer_number) { + if (WindowCmd::window() == 0) + return; + WindowCmd::window()->moveToLayer(layer_number); + } + int layerNumber() const { + if (WindowCmd::window() == 0) + return -1; + return WindowCmd::window()->layerItem().getLayerNum(); + } + } static context; + + FbTk::Menu *submenu = new LayerMenu(screen->menuTheme(), + screen->imageControl(), + *screen->layerManager(). + getLayer(Fluxbox::instance()->getMenuLayer()), + &context, + false); submenu->disableTitle(); menu.insert(label.empty()?_FBTEXT(Windowmenu, Layer, "Layer ...", "Layer menu"):label.c_str(), submenu); diff --git a/src/MenuCreator.hh b/src/MenuCreator.hh index a2a4a4b..66e7408 100644 --- a/src/MenuCreator.hh +++ b/src/MenuCreator.hh @@ -39,10 +39,11 @@ public: static FbTk::Menu *createMenuType(const std::string &label, int screen_num); static bool createFromFile(const std::string &filename, FbTk::Menu &inject_into, bool require_begin); - static bool createFromFile(const std::string &filename, FbTk::Menu &inject_into, - FluxboxWindow &win, bool require_begin); + static bool createWindowMenuFromFile(const std::string &filename, FbTk::Menu &inject_into, + bool require_begin); static bool createWindowMenuItem(const std::string &type, const std::string &label, - FbTk::Menu &inject_into, FluxboxWindow &win); + FbTk::Menu &inject_into); + }; #endif // MENUCREATOR_HH diff --git a/src/Remember.cc b/src/Remember.cc index e3d3db0..9eae24b 100644 --- a/src/Remember.cc +++ b/src/Remember.cc @@ -31,6 +31,7 @@ #include "FbMenu.hh" #include "FbCommands.hh" #include "fluxbox.hh" +#include "WindowCmd.hh" #include "FbTk/I18n.hh" #include "FbTk/StringUtil.hh" @@ -60,53 +61,58 @@ namespace { class RememberMenuItem : public FbTk::MenuItem { public: - RememberMenuItem(const char *label, Remember &remember, - FluxboxWindow &fbwin, + RememberMenuItem(const char *label, Remember::Attribute attrib) : - FbTk::MenuItem(label), m_remember(remember), - m_win(fbwin), m_attrib(attrib) { + FbTk::MenuItem(label), + m_attrib(attrib) { setToggleItem(true); } bool isSelected() const { - if (m_win.numClients()) // ensure it HAS clients - return m_remember.isRemembered(m_win.winClient(), m_attrib); + if (WindowCmd::window() == 0) + return false; + + if (WindowCmd::window()->numClients()) // ensure it HAS clients + return Remember::instance().isRemembered(WindowCmd::window()->winClient(), m_attrib); else return false; } bool isEnabled() const { + if (WindowCmd::window() == 0) + return false; + if (m_attrib != Remember::REM_JUMPWORKSPACE) return true; - else if (m_win.numClients()) - return (m_remember.isRemembered(m_win.winClient(), Remember::REM_WORKSPACE)); + else if (WindowCmd::window()->numClients()) + return (Remember::instance().isRemembered(WindowCmd::window()->winClient(), Remember::REM_WORKSPACE)); else return false; } void click(int button, int time) { - if (isSelected()) { - m_remember.forgetAttrib(m_win.winClient(), m_attrib); - } else { - m_remember.rememberAttrib(m_win.winClient(), m_attrib); + if (WindowCmd::window() != 0) { + if (isSelected()) { + Remember::instance().forgetAttrib(WindowCmd::window()->winClient(), m_attrib); + } else { + Remember::instance().rememberAttrib(WindowCmd::window()->winClient(), m_attrib); + } } - m_remember.save(); + Remember::instance().save(); FbTk::MenuItem::click(button, time); } private: - // my remember manager - Remember &m_remember; - FluxboxWindow &m_win; Remember::Attribute m_attrib; }; -FbTk::Menu *createRememberMenu(Remember &remember, FluxboxWindow &win, bool enabled) { +FbTk::Menu *createRememberMenu(BScreen &screen) { // each fluxboxwindow has its own windowmenu // so we also create a remember menu just for it... - FbTk::Menu *menu = win.screen().createMenu(""); + FbTk::Menu *menu = screen.createMenu(""); // if enabled, then we want this to be a unavailable menu + /* if (!enabled) { FbTk::MenuItem *item = new FbTk::MenuItem("unavailable"); item->setEnabled(false); @@ -114,28 +120,28 @@ FbTk::Menu *createRememberMenu(Remember &remember, FluxboxWindow &win, bool enab menu->updateMenu(); return menu; } - + */ _FB_USES_NLS; menu->insert(new RememberMenuItem(_FBTEXT(Remember, Workspace, "Workspace", "Remember Workspace"), - remember, win, Remember::REM_WORKSPACE)); + Remember::REM_WORKSPACE)); menu->insert(new RememberMenuItem(_FBTEXT(Remember, JumpToWorkspace, "Jump to workspace", "Change active workspace to remembered one on open"), - remember, win, Remember::REM_JUMPWORKSPACE)); + Remember::REM_JUMPWORKSPACE)); menu->insert(new RememberMenuItem(_FBTEXT(Remember, Head, "Head", "Remember Head"), - remember, win, Remember::REM_HEAD)); + Remember::REM_HEAD)); menu->insert(new RememberMenuItem(_FBTEXT(Remember, Dimensions, "Dimensions", "Remember Dimensions - with width and height"), - remember, win, Remember::REM_DIMENSIONS)); + Remember::REM_DIMENSIONS)); menu->insert(new RememberMenuItem(_FBTEXT(Remember, Position, "Position", "Remember position - window co-ordinates"), - remember, win, Remember::REM_POSITION)); + Remember::REM_POSITION)); menu->insert(new RememberMenuItem(_FBTEXT(Remember, Sticky, "Sticky", "Remember Sticky"), - remember, win, Remember::REM_STUCKSTATE)); + Remember::REM_STUCKSTATE)); menu->insert(new RememberMenuItem(_FBTEXT(Remember, Decorations, "Decorations", "Remember window decorations"), - remember, win, Remember::REM_DECOSTATE)); + Remember::REM_DECOSTATE)); menu->insert(new RememberMenuItem(_FBTEXT(Remember, Shaded, "Shaded", "Remember shaded"), - remember, win, Remember::REM_SHADEDSTATE)); + Remember::REM_SHADEDSTATE)); menu->insert(new RememberMenuItem(_FBTEXT(Remember, Layer, "Layer", "Remember Layer"), - remember, win, Remember::REM_LAYER)); + Remember::REM_LAYER)); menu->insert(new RememberMenuItem(_FBTEXT(Remember, SaveOnClose, "Save on close", "Save remembered attributes on close"), - remember, win, Remember::REM_SAVEONCLOSE)); + Remember::REM_SAVEONCLOSE)); menu->updateMenu(); return menu; @@ -217,16 +223,23 @@ Application::Application(bool grouped) save_on_close_remember = false; } -/******************************************************** +/************ * Remember * ************/ +Remember *Remember::s_instance = 0; + Remember::Remember() { + if (s_instance != 0) + throw string("Can not create more than one instance of Remember"); + + s_instance = this; enableUpdate(); load(); } Remember::~Remember() { + // free our resources // the patterns free the "Application"s @@ -245,6 +258,8 @@ Remember::~Remember() { delete (*ait); ++ait; } + + s_instance = 0; } Application* Remember::find(WinClient &winclient) { @@ -811,9 +826,6 @@ void Remember::setupFrame(FluxboxWindow &win) { // we don't touch the window if it is a transient // of something else - // All windows get the remember menu. - win.addExtraMenu(_FBTEXT(Remember, MenuItemName, "Remember...", "Remember item in menu"), - createRememberMenu(*this, win, (winclient.transientFor() == 0))); if (winclient.transientFor()) return; @@ -936,6 +948,13 @@ void Remember::updateClientClose(WinClient &winclient) { } +void Remember::initForScreen(BScreen &screen) { + // All windows get the remember menu. + screen.addExtraWindowMenu(_FBTEXT(Remember, MenuItemName, "Remember...", "Remember item in menu"), + createRememberMenu(screen)); + +} + void Remember::updateFrameClose(FluxboxWindow &win) { // scan all applications and remove this fbw if it is a recorded group Patterns::iterator it = m_pats.begin(); diff --git a/src/Screen.cc b/src/Screen.cc index 5b903b1..926193d 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -367,7 +367,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm, #endif // SLIT rm.unlock(); - + XFlush(disp); } @@ -384,6 +384,7 @@ void destroyAndClearList(A &a) { BScreen::~BScreen() { + if (! managed) return; @@ -394,6 +395,24 @@ BScreen::~BScreen() { // we need to destroy it before we destroy workspaces m_workspacemenu.reset(0); + ExtraMenus::iterator mit = m_extramenus.begin(); + ExtraMenus::iterator mit_end = m_extramenus.end(); + for (; mit != mit_end; ++mit) { + // we set them to NOT internal so that they will be deleted when the + // menu is cleaned up. We can't delete them here because they are + // still in the menu + // (They need to be internal for most of the time so that if we + // rebuild the menu, then they won't be removed. + if (mit->second->parent() == 0) { + // not attached to our windowmenu + // so we clean it up + delete mit->second; + } else { + // let the parent clean it up + mit->second->setInternalMenu(false); + } + } + if (geom_pixmap != None) imageControl().removeImage(geom_pixmap); @@ -601,6 +620,25 @@ FbTk::Menu *BScreen::createMenu(const std::string &label) { return menu; } +void BScreen::addExtraWindowMenu(const char *label, FbTk::Menu *menu) { + menu->setInternalMenu(); + menu->disableTitle(); + m_extramenus.push_back(std::make_pair(label, menu)); + // recreate window menu + m_windowmenu.reset(MenuCreator::createMenuType("windowmenu", screenNumber())); +} + +void BScreen::removeExtraWindowMenu(FbTk::Menu *menu) { + ExtraMenus::iterator it = find_if(m_extramenus.begin(), + m_extramenus.end(), + FbTk::Compose(bind2nd(equal_to(), menu), + FbTk::Select2nd())); + if (it != m_extramenus.end()) + m_extramenus.erase(it); + // recreate window menu + m_windowmenu.reset(MenuCreator::createMenuType("windowmenu", screenNumber())); +} + void BScreen::hideMenus() { // hide extra menus Fluxbox::instance()->hideExtraMenus(*this); @@ -684,6 +722,8 @@ void BScreen::reconfigure() { //reconfigure menus m_workspacemenu->reconfigure(); m_configmenu->reconfigure(); + // recreate window menu + m_windowmenu.reset(MenuCreator::createMenuType("windowmenu", screenNumber())); // We need to check to see if the timestamps // changed before we actually can restore the menus @@ -963,9 +1003,11 @@ void BScreen::sendToWorkspace(unsigned int id, FluxboxWindow *win, bool changeWS win->deiconify(); // if the window isn't on current workspace, hide it - if (id != currentWorkspace()->workspaceID()) + if (id != currentWorkspace()->workspaceID()) win->withdraw(true); + windowMenu().hide(); + reassociateWindow(win, id, true); // if the window is on current workspace, show it. @@ -1649,9 +1691,11 @@ void BScreen::dirFocus(FluxboxWindow &win, const FocusDir dir) { } void BScreen::initMenus() { m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber())); + m_windowmenu.reset(MenuCreator::createMenuType("windowmenu", screenNumber())); initMenu(); } + void BScreen::initMenu() { if (m_rootmenu.get()) { diff --git a/src/Screen.hh b/src/Screen.hh index cb18cdd..abebd02 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -97,6 +97,7 @@ public: typedef std::list FocusedWindows; typedef std::vector Workspaces; typedef std::vector WorkspaceNames; + typedef std::list > ExtraMenus; BScreen(FbTk::ResourceManager &rm, const std::string &screenname, const std::string &altscreenname, @@ -123,10 +124,16 @@ public: inline bool decorateTransient() const { return *resource.decorate_transient; } inline const std::string &windowMenuFilename() const { return *resource.windowmenufile; } inline FbTk::ImageControl &imageControl() { return *m_image_control.get(); } + // menus const FbTk::Menu &getRootmenu() const { return *m_rootmenu.get(); } FbTk::Menu &getRootmenu() { return *m_rootmenu.get(); } const FbTk::Menu &configMenu() const { return *m_configmenu.get(); } FbTk::Menu &configMenu() { return *m_configmenu.get(); } + const FbTk::Menu &windowMenu() const { return *m_windowmenu.get(); } + FbTk::Menu &windowMenu() { return *m_windowmenu.get(); } + + ExtraMenus &extraWindowMenus() { return m_extramenus; } + const ExtraMenus &extraWindowMenus() const { return m_extramenus; } inline const std::string &getRootCommand() const { return *resource.rootcommand; } inline ResizeModel getResizeModel() const { return *resource.resize_model; } @@ -199,6 +206,11 @@ public: FbTk::Menu *createMenu(const std::string &label); void hideMenus(); + // for extras to add menus. + // These menus will be marked internal, + // and deleted when the window dies (as opposed to Screen + void addExtraWindowMenu(const char *label, FbTk::Menu *menu); + void removeExtraWindowMenu(FbTk::Menu *menu); /// hide all windowmenus except the given one (if given) void hideWindowMenus(const FluxboxWindow* except= 0); @@ -393,7 +405,9 @@ private: std::auto_ptr m_image_control; - std::auto_ptr m_configmenu, m_rootmenu, m_workspacemenu; + std::auto_ptr m_configmenu, m_rootmenu, m_workspacemenu, m_windowmenu; + + ExtraMenus m_extramenus; typedef std::list Rootmenus; typedef std::list Netizens; diff --git a/src/SendToMenu.cc b/src/SendToMenu.cc index c039f16..f0f1dda 100644 --- a/src/SendToMenu.cc +++ b/src/SendToMenu.cc @@ -28,39 +28,36 @@ #include "Screen.hh" #include "fluxbox.hh" #include "Workspace.hh" +#include "WindowCmd.hh" #include "FbTk/MultiButtonMenuItem.hh" #include "FbTk/Command.hh" class SendToCmd: public FbTk::Command { public: - SendToCmd(FluxboxWindow &win, int workspace, bool follow): - m_win(win), + SendToCmd(int workspace, bool follow): m_workspace(workspace), m_follow(follow) { } void execute() { - m_win.screen().sendToWorkspace(m_workspace, &m_win, m_follow); + if (WindowCmd::window() != 0) + WindowCmd::window()->screen().sendToWorkspace(m_workspace, WindowCmd::window(), m_follow); } private: - FluxboxWindow &m_win; const int m_workspace; const bool m_follow; }; -SendToMenu::SendToMenu(FluxboxWindow &win): - FbMenu(win.screen().menuTheme(), - win.screen().imageControl(), - *win.screen().layerManager().getLayer(Fluxbox::instance()->getMenuLayer())), - m_win(win) { +SendToMenu::SendToMenu(BScreen &screen): + FbMenu(screen.menuTheme(), + screen.imageControl(), + *screen.layerManager().getLayer(Fluxbox::instance()->getMenuLayer())) { // listen to: // workspace count signal // workspace names signal // current workspace signal - // and window's workspace sig - win.screen().workspaceCountSig().attach(this); - win.screen().workspaceNamesSig().attach(this); - win.screen().currentWorkspaceSig().attach(this); - win.workspaceSig().attach(this); + screen.workspaceCountSig().attach(this); + screen.workspaceNamesSig().attach(this); + screen.currentWorkspaceSig().attach(this); disableTitle(); // build menu @@ -69,19 +66,7 @@ SendToMenu::SendToMenu(FluxboxWindow &win): void SendToMenu::update(FbTk::Subject *subj) { if (subj != 0) { - // if workspace changed we enable all workspaces except the current one - if (subj == &(m_win.screen().currentWorkspaceSig()) || - subj == &(m_win.workspaceSig())) { - // enabled all workspaces - const BScreen::Workspaces &wlist = m_win.screen().getWorkspacesList(); - for (size_t i = 0; i < wlist.size(); ++i) - setItemEnabled(i, true); - // disable send to on the workspace which the window exist - setItemEnabled(m_win.workspaceNumber(), false); - updateMenu(); - // we're done - return; - } else if (subj == &(theme().reconfigSig())) { + if (subj == &(theme().reconfigSig())) { // we got reconfig Theme signal, let base menu handle it FbTk::Menu::update(subj); return; @@ -91,11 +76,11 @@ void SendToMenu::update(FbTk::Subject *subj) { // rebuild menu removeAll(); - - const BScreen::Workspaces &wlist = m_win.screen().getWorkspacesList(); + BScreen *screen = Fluxbox::instance()->findScreen(screenNumber()); + const BScreen::Workspaces &wlist = screen->getWorkspacesList(); for (size_t i = 0; i < wlist.size(); ++i) { - FbTk::RefCount sendto_cmd(new SendToCmd(m_win, i, false)); - FbTk::RefCount sendto_follow_cmd(new SendToCmd(m_win, i, true)); + FbTk::RefCount sendto_cmd(new SendToCmd(i, false)); + FbTk::RefCount sendto_follow_cmd(new SendToCmd(i, true)); FbTk::MultiButtonMenuItem* item = new FbTk::MultiButtonMenuItem(3, wlist[i]->name().c_str()); item->setCommand(1, sendto_cmd); @@ -104,7 +89,16 @@ void SendToMenu::update(FbTk::Subject *subj) { insert(item); } - setItemEnabled(m_win.workspaceNumber(), false); - updateMenu(); } + +void SendToMenu::show() { + if (WindowCmd::window() != 0) { + for (unsigned int i=0; i < numberOfItems(); ++i) + setItemEnabled(i, true); + setItemEnabled(WindowCmd::window()->workspaceNumber(), false); + updateMenu(); + } + FbTk::Menu::show(); +} + diff --git a/src/SendToMenu.hh b/src/SendToMenu.hh index 1784a7c..31c9e19 100644 --- a/src/SendToMenu.hh +++ b/src/SendToMenu.hh @@ -29,16 +29,15 @@ #include "FbTk/Observer.hh" -class FluxboxWindow; +class BScreen; class SendToMenu:public FbMenu { public: - explicit SendToMenu(FluxboxWindow &win); + explicit SendToMenu(BScreen &win); virtual ~SendToMenu() { } + void show(); protected: void update(FbTk::Subject *subj); -private: - FluxboxWindow &m_win; }; #endif // SENDTOMENU_HH diff --git a/src/Slit.cc b/src/Slit.cc index eb26320..6656dec 100644 --- a/src/Slit.cc +++ b/src/Slit.cc @@ -313,16 +313,18 @@ Slit::Slit(BScreen &scr, FbTk::XLayer &layer, const char *filename) } m_layeritem.reset(new FbTk::XLayerItem(frame.window, layer)); - m_layermenu.reset(new LayerMenu(scr.menuTheme(), - scr.imageControl(), - *scr.layerManager(). - getLayer(Fluxbox::instance()->getMenuLayer()), - this, - true)); + + m_layermenu.reset(new LayerMenu(scr.menuTheme(), + scr.imageControl(), + *scr.layerManager(). + getLayer(Fluxbox::instance()->getMenuLayer()), + this, + true)); + m_layermenu->setLabel(_FBTEXT(Slit, Layer, "Slit Layer", "Title of Slit Layer Menu")); + moveToLayer((*m_rc_layernum).getNum()); - if (m_layermenu.get()) - m_layermenu->setLabel(_FBTEXT(Slit, Layer, "Slit Layer", "Title of Slit Layer Menu")); + // Get client list for sorting purposes loadClientList(filename); diff --git a/src/Slit.hh b/src/Slit.hh index 81322b3..45d5993 100644 --- a/src/Slit.hh +++ b/src/Slit.hh @@ -27,11 +27,15 @@ #ifndef SLIT_HH #define SLIT_HH -#include "Menu.hh" -#include "FbWindow.hh" -#include "Timer.hh" -#include "XLayerItem.hh" + #include "LayerMenu.hh" +#include "fluxbox.hh" + +#include "FbTk/Menu.hh" +#include "FbTk/FbWindow.hh" +#include "FbTk/Timer.hh" +#include "FbTk/Resource.hh" +#include "FbTk/XLayerItem.hh" #include #include @@ -47,7 +51,7 @@ class FbMenu; class Strut; /// Handles dock apps -class Slit: public FbTk::EventHandler, public FbTk::Observer { +class Slit: public FbTk::EventHandler, public FbTk::Observer, public LayerObject { public: typedef std::list SlitClients; /** @@ -105,7 +109,8 @@ public: SlitTheme &theme() { return *m_slit_theme.get(); } const SlitTheme &theme() const { return *m_slit_theme.get(); } - FbTk::XLayerItem &layerItem() { return *m_layeritem; } + int layerNumber() const { return m_layeritem->getLayerNum(); } + inline bool isHidden() const { return m_hidden; } inline bool doAutoHide() const { return *m_rc_auto_hide; } inline Direction direction() const { return *m_rc_direction; } @@ -141,7 +146,7 @@ private: SlitClients m_client_list; FbMenu m_slitmenu, m_placement_menu, m_clientlist_menu; - std::auto_ptr > m_layermenu; + std::auto_ptr m_layermenu; std::string m_filename; struct frame { diff --git a/src/ToggleMenu.hh b/src/ToggleMenu.hh index 794c016..cee8505 100644 --- a/src/ToggleMenu.hh +++ b/src/ToggleMenu.hh @@ -51,7 +51,7 @@ public: // force full foreground update frameWindow().updateBackground(false); } - + clearWindow(); } }; diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 0f16140..8b5def2 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -826,7 +826,7 @@ void Toolbar::setupMenus() { menu().insert(new BoolMenuItem(_FBTEXT(Common, MaximizeOver,"Maximize Over", "Maximize over this thing when maximizing"), *m_rc_maximize_over, reconfig_toolbar_and_save_resource)); - menu().insert(_FBTEXT(Menu, Layer, "Layer...", "Title of Layer menu"), &layermenu()); + menu().insert(_FBTEXT(Menu, Layer, "Layer...", "Title of Layer menu"), &layerMenu()); diff --git a/src/Toolbar.hh b/src/Toolbar.hh index ee9b20d..2f8bed6 100644 --- a/src/Toolbar.hh +++ b/src/Toolbar.hh @@ -31,6 +31,7 @@ #include "LayerMenu.hh" #include "ToolFactory.hh" #include "ToolTheme.hh" +#include "fluxbox.hh" #include "FbTk/Timer.hh" #include "FbTk/Resource.hh" @@ -54,7 +55,7 @@ class ImageControl; /// The toolbar. /// Handles iconbar, workspace name view and clock view -class Toolbar: public FbTk::EventHandler, public FbTk::Observer { +class Toolbar: public FbTk::EventHandler, public FbTk::Observer, public LayerObject { public: /// Toolbar placement on the screen @@ -101,15 +102,15 @@ public: void update(FbTk::Subject *subj); - FbTk::XLayerItem &layerItem() { return m_layeritem; } + int layerNumber() const { return const_cast(m_layeritem).getLayerNum(); } inline const FbTk::Menu &menu() const { return m_toolbarmenu; } inline FbTk::Menu &menu() { return m_toolbarmenu; } inline FbTk::Menu &placementMenu() { return m_placementmenu; } inline const FbTk::Menu &placementMenu() const { return m_placementmenu; } - inline FbTk::Menu &layermenu() { return m_layermenu; } - inline const FbTk::Menu &layermenu() const { return m_layermenu; } + inline FbTk::Menu &layerMenu() { return m_layermenu; } + inline const FbTk::Menu &layerMenu() const { return m_layermenu; } /// are we hidden? inline bool isHidden() const { return m_hidden; } @@ -163,8 +164,8 @@ private: FbTk::Timer m_hide_timer; ///< timer to for auto hide toolbar FbTk::XLayerItem m_layeritem; ///< layer item, must be declared before layermenu - LayerMenu m_layermenu; - FbMenu m_placementmenu, m_toolbarmenu; + LayerMenu m_layermenu; + FbMenu m_placementmenu, m_toolbarmenu; // themes diff --git a/src/Window.cc b/src/Window.cc index 6d33a5c..5f45ce8 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -36,6 +36,7 @@ #include "FbWinFrame.hh" #include "WinButton.hh" #include "WinButtonTheme.hh" +#include "WindowCmd.hh" #include "Remember.hh" #include "MenuCreator.hh" @@ -294,7 +295,6 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbWinFrameTheme &tm, m_attaching_tab(0), m_screen(client.screen()), display(FbTk::App::instance()->display()), - m_windowmenu(MenuCreator::createMenu("", client.screenNumber())), m_button_grab_x(0), m_button_grab_y(0), m_last_move_x(0), m_last_move_y(0), m_last_resize_h(1), m_last_resize_w(1), @@ -323,6 +323,9 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbWinFrameTheme &tm, FluxboxWindow::~FluxboxWindow() { + if (WindowCmd::window() == this) + WindowCmd::setWindow(0); + #ifdef DEBUG cerr<<__FILE__<<"("<<__LINE__<<"): starting ~FluxboxWindow("<(menu().width()) >= static_cast(screen().maxRight(head))) menu_x = screen().maxRight(head) - menu().width() - 1; - + WindowCmd::setWindow(this); menu().move(menu_x, menu_y); menu().show(); menu().raise(); @@ -2275,6 +2260,8 @@ void FluxboxWindow::showMenu(int menu_x, int menu_y) { if it's already visible it'll be hidden */ void FluxboxWindow::popupMenu() { + WindowCmd::setWindow(this); + if (menu().isVisible()) { menu().hide(); return; @@ -3553,6 +3540,14 @@ const FbTk::FbWindow &FluxboxWindow::fbWindow() const { return frame().window(); } +FbTk::Menu &FluxboxWindow::menu() { + return screen().windowMenu(); +} + +const FbTk::Menu &FluxboxWindow::menu() const { + return screen().windowMenu(); +} + unsigned int FluxboxWindow::titlebarHeight() const { return frame().titlebarHeight(); } @@ -3736,24 +3731,6 @@ void FluxboxWindow::sendConfigureNotify(bool send_to_netizens) { } // end for } -void FluxboxWindow::addExtraMenu(const char *label, FbTk::Menu *menu) { - menu->setInternalMenu(); - menu->disableTitle(); - m_extramenus.push_back(std::make_pair(label, menu)); - - setupMenu(); -} - -void FluxboxWindow::removeExtraMenu(FbTk::Menu *menu) { - ExtraMenus::iterator it = find_if(m_extramenus.begin(), - m_extramenus.end(), - Compose(bind2nd(equal_to(), menu), - Select2nd())); - if (it != m_extramenus.end()) - m_extramenus.erase(it); - - setupMenu(); -} void FluxboxWindow::close() { if (m_client) @@ -3870,33 +3847,6 @@ void FluxboxWindow::setupWindow() { // end setup frame - setupMenu(); -} - -void FluxboxWindow::setupMenu() { - // setup menu - - menu().removeAll(); // clear old items - menu().disableTitle(); // not titlebar - - if (screen().windowMenuFilename().empty() || - ! MenuCreator::createFromFile(screen().windowMenuFilename(), menu(), *this, true)) - - { - MenuCreator::createWindowMenuItem("shade", "", menu(), *this); - MenuCreator::createWindowMenuItem("stick", "", menu(), *this); - MenuCreator::createWindowMenuItem("maximize", "", menu(), *this); - MenuCreator::createWindowMenuItem("iconify", "", menu(), *this); - MenuCreator::createWindowMenuItem("raise", "", menu(), *this); - MenuCreator::createWindowMenuItem("lower", "", menu(), *this); - MenuCreator::createWindowMenuItem("sendto", "", menu(), *this); - MenuCreator::createWindowMenuItem("layer", "", menu(), *this); - MenuCreator::createWindowMenuItem("extramenus", "", menu(), *this); - MenuCreator::createWindowMenuItem("separator", "", menu(), *this); - MenuCreator::createWindowMenuItem("close", "", menu(), *this); - } - - menu().reconfigure(); // update graphics } diff --git a/src/Window.hh b/src/Window.hh index ee53036..6d0c77f 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -31,7 +31,6 @@ #include "FbTk/Subject.hh" #include "FbTk/EventHandler.hh" #include "FbTk/XLayerItem.hh" - #include "FbWinFrame.hh" #include @@ -153,8 +152,6 @@ public: } BlackboxAttributes; typedef std::list ClientList; - // this should perhaps be a refcount?? - typedef std::list > ExtraMenus; /// create a window from a client FluxboxWindow(WinClient &client, @@ -322,18 +319,8 @@ public: FbTk::FbWindow &fbWindow(); const FbTk::FbWindow &fbWindow() const; - FbTk::Menu &menu() { return *m_windowmenu.get(); } - const FbTk::Menu &menu() const { return *m_windowmenu.get(); } - - - // for extras to add menus. - // These menus will be marked internal, - // and deleted when the window dies (as opposed to Screen - void addExtraMenu(const char *label, FbTk::Menu *menu); - void removeExtraMenu(FbTk::Menu *menu); - - ExtraMenus &extraMenus() { return m_extramenus; } - const ExtraMenus &extraMenus() const { return m_extramenus; } + FbTk::Menu &menu(); + const FbTk::Menu &menu() const; const FbTk::FbWindow &parent() const { return m_parent; } FbTk::FbWindow &parent() { return m_parent; } @@ -398,7 +385,6 @@ private: static const int PropBlackboxAttributesElements = 8; void setupWindow(); - void setupMenu(); void init(); /// applies a shape mask to the window if it has one @@ -474,8 +460,6 @@ private: Display *display; /// display connection BlackboxAttributes m_blackbox_attrib; - std::auto_ptr m_windowmenu; - timeval m_last_focus_time; int m_button_grab_x, m_button_grab_y; // handles last button press event for move @@ -524,7 +508,6 @@ private: ResizeCorner m_resize_corner; - ExtraMenus m_extramenus; static int s_num_grabs; ///< number of XGrabPointer's }; diff --git a/src/Workspace.cc b/src/Workspace.cc index 8a6bdbb..28c2c34 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -31,6 +31,7 @@ #include "Window.hh" #include "WinClient.hh" #include "FbWinFrame.hh" +#include "WindowCmd.hh" #include "FbTk/I18n.hh" #include "FbTk/MenuItem.hh" @@ -83,10 +84,18 @@ int countTransients(const WinClient &client) { class ClientMenuItem:public FbTk::MenuItem { public: ClientMenuItem(WinClient &client): - FbTk::MenuItem(client.title().c_str(), client.fbwindow() ? &client.fbwindow()->menu() : 0), + FbTk::MenuItem(client.title().c_str(), &client.screen().windowMenu()), 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; -- cgit v0.11.2