moved window menu from FluxboxWindow to BScreen

This commit is contained in:
fluxgen 2005-06-23 03:07:25 +00:00
parent 18cf586249
commit 5373f6d840
16 changed files with 303 additions and 283 deletions

View file

@ -25,91 +25,46 @@
#ifndef LAYERMENU_HH #ifndef LAYERMENU_HH
#define LAYERMENU_HH #define LAYERMENU_HH
#include "MenuItem.hh"
#include "ToggleMenu.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 /// this class holds the layermenu items
template <typename ItemType>
class LayerMenuItem : public FbTk::MenuItem { class LayerMenuItem : public FbTk::MenuItem {
public: public:
LayerMenuItem(const char *label, ItemType *object, int layernum, LayerMenuItem(const char *label, LayerObject *object, int layernum,
FbTk::RefCount<FbTk::Command> &cmd): FbTk::RefCount<FbTk::Command> &cmd):
FbTk::MenuItem(label,cmd), m_object(object), m_layernum(layernum) {} FbTk::MenuItem(label, cmd), m_object(object), m_layernum(layernum) {}
LayerMenuItem(const char *label, ItemType *object, int layernum):
LayerMenuItem(const char *label, LayerObject *object, int layernum):
FbTk::MenuItem(label), m_object(object), m_layernum(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) { void click(int button, int time) {
m_object->moveToLayer(m_layernum); m_object->moveToLayer(m_layernum);
FbTk::MenuItem::click(button, time); FbTk::MenuItem::click(button, time);
} }
private: private:
ItemType *m_object; LayerObject *m_object;
int m_layernum; int m_layernum;
}; };
/// Create a layer menu inside from the given menu /// Create a layer menu inside from the given menu
template <typename ItemType>
class LayerMenu : public ToggleMenu { class LayerMenu : public ToggleMenu {
public: public:
LayerMenu(MenuTheme &tm, FbTk::ImageControl &imgctrl, 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 <typename ItemType>
LayerMenu<ItemType>::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<FbTk::Command> saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(
*Fluxbox::instance(),
&Fluxbox::save_rc));
for (size_t i=0; i < 6; ++i) {
// TODO: fetch nls string
if (save_rc) {
insert(new LayerMenuItem<ItemType>(layer_menuitems[i].default_str,
m_object, layer_menuitems[i].layernum, saverc_cmd));
} else {
insert(new LayerMenuItem<ItemType>(layer_menuitems[i].default_str,
m_object, layer_menuitems[i].layernum));
}
}
updateMenu();
}
#endif // LAYERMENU_HH #endif // LAYERMENU_HH

View file

@ -29,6 +29,7 @@
#include "fluxbox.hh" #include "fluxbox.hh"
#include "CommandParser.hh" #include "CommandParser.hh"
#include "Window.hh" #include "Window.hh"
#include "WindowCmd.hh"
#include "FbMenu.hh" #include "FbMenu.hh"
#include "IconMenu.hh" #include "IconMenu.hh"
@ -53,11 +54,6 @@
#include <iostream> #include <iostream>
using namespace std; using namespace std;
template <>
void LayerMenuItem<FluxboxWindow>::click(int button, int time) {
m_object->moveToLayer(m_layernum);
}
static void createStyleMenu(FbTk::Menu &parent, const std::string &label, static void createStyleMenu(FbTk::Menu &parent, const std::string &label,
const std::string &directory) { const std::string &directory) {
// perform shell style ~ home directory expansion // perform shell style ~ home directory expansion
@ -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); ParseItem pitem(&menu);
while (!parse.eof()) { while (!parse.eof()) {
pitem.load(parse); pitem.load(parse);
if (MenuCreator::createWindowMenuItem(pitem.key(), pitem.label(), menu, win)) if (MenuCreator::createWindowMenuItem(pitem.key(), pitem.label(), menu))
continue; continue;
if (pitem.key() == "end") { if (pitem.key() == "end") {
return; return;
} else if (pitem.key() == "submenu") { } else if (pitem.key() == "submenu") {
FbTk::Menu *submenu = MenuCreator::createMenu(pitem.label(), menu.screenNumber()); FbTk::Menu *submenu = MenuCreator::createMenu(pitem.label(), menu.screenNumber());
parseWindowMenu(parse, *submenu, win); parseWindowMenu(parse, *submenu);
submenu->updateMenu(); submenu->updateMenu();
menu.insert(pitem.label().c_str(), submenu); 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, bool MenuCreator::createWindowMenuFromFile(const std::string &filename,
FbTk::Menu &inject_into, FbTk::Menu &inject_into,
FluxboxWindow &win, bool require_begin) { bool require_begin) {
std::string real_filename = FbTk::StringUtil::expandFilename(filename); std::string real_filename = FbTk::StringUtil::expandFilename(filename);
FbMenuParser parser(real_filename); FbMenuParser parser(real_filename);
if (!parser.isLoaded()) if (!parser.isLoaded())
@ -429,7 +425,7 @@ bool MenuCreator::createFromFile(const std::string &filename,
if (require_begin && !getStart(parser, label)) if (require_begin && !getStart(parser, label))
return false; return false;
parseWindowMenu(parser, inject_into, win); parseWindowMenu(parser, inject_into);
return true; return true;
} }
@ -442,26 +438,56 @@ FbTk::Menu *MenuCreator::createMenuType(const std::string &type, int screen_num)
return new IconMenu(*screen); return new IconMenu(*screen);
} else if (type == "workspacemenu") { } else if (type == "workspacemenu") {
return new WorkspaceMenu(*screen); 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; return 0;
} }
bool MenuCreator::createWindowMenuItem(const std::string &type, bool MenuCreator::createWindowMenuItem(const std::string &type,
const std::string &label, const std::string &label,
FbTk::Menu &menu, FbTk::Menu &menu) {
FluxboxWindow &win) {
typedef FbTk::RefCount<FbTk::Command> RefCmd; typedef FbTk::RefCount<FbTk::Command> RefCmd;
typedef FbTk::SimpleCommand<FluxboxWindow> WindowCmd;
_FB_USES_NLS; _FB_USES_NLS;
if (type == "shade") { if (type == "shade") {
RefCmd shade_cmd(new WindowCmd(win, &FluxboxWindow::shade)); RefCmd shade_cmd(new WindowCmd<void>(&FluxboxWindow::shade));
menu.insert(label.empty()?_FBTEXT(Windowmenu, Shade, "Shade", "Shade the window"):label.c_str(), shade_cmd); menu.insert(label.empty()?_FBTEXT(Windowmenu, Shade, "Shade", "Shade the window"):label.c_str(), shade_cmd);
} else if (type == "maximize") { } else if (type == "maximize") {
RefCmd maximize_cmd(new WindowCmd(win, &FluxboxWindow::maximizeFull)); RefCmd maximize_cmd(new WindowCmd<void>(&FluxboxWindow::maximizeFull));
RefCmd maximize_vert_cmd(new WindowCmd(win, &FluxboxWindow::maximizeVertical)); RefCmd maximize_vert_cmd(new WindowCmd<void>(&FluxboxWindow::maximizeVertical));
RefCmd maximize_horiz_cmd(new WindowCmd(win, &FluxboxWindow::maximizeHorizontal)); RefCmd maximize_horiz_cmd(new WindowCmd<void>(&FluxboxWindow::maximizeHorizontal));
FbTk::MultiButtonMenuItem *maximize_item = new FbTk::MultiButtonMenuItem(3, label.empty()?_FBTEXT(Windowmenu, Maximize, "Maximize", "Maximize the window"):label.c_str()); FbTk::MultiButtonMenuItem *maximize_item =
new FbTk::MultiButtonMenuItem(3,
label.empty()?
_FBTEXT(Windowmenu, Maximize,
"Maximize", "Maximize the window"):
label.c_str());
// create maximize item with: // create maximize item with:
// button1: Maximize normal // button1: Maximize normal
// button2: Maximize Vertical // button2: Maximize Vertical
@ -471,42 +497,60 @@ bool MenuCreator::createWindowMenuItem(const std::string &type,
maximize_item->setCommand(3, maximize_horiz_cmd); maximize_item->setCommand(3, maximize_horiz_cmd);
menu.insert(maximize_item); menu.insert(maximize_item);
} else if (type == "iconify") { } else if (type == "iconify") {
RefCmd iconify_cmd(new WindowCmd(win, &FluxboxWindow::iconify)); RefCmd iconify_cmd(new WindowCmd<void>(&FluxboxWindow::iconify));
menu.insert(label.empty()?_FBTEXT(Windowmenu, Iconify, "Iconify", "Iconify the window"):label.c_str(), iconify_cmd); menu.insert(label.empty()?_FBTEXT(Windowmenu, Iconify, "Iconify", "Iconify the window"):label.c_str(), iconify_cmd);
} else if (type == "close") { } else if (type == "close") {
RefCmd close_cmd(new WindowCmd(win, &FluxboxWindow::close)); RefCmd close_cmd(new WindowCmd<void>(&FluxboxWindow::close));
menu.insert(label.empty()?_FBTEXT(Windowmenu, Close, "Close", "Close the window"):label.c_str(), close_cmd); menu.insert(label.empty()?_FBTEXT(Windowmenu, Close, "Close", "Close the window"):label.c_str(), close_cmd);
} else if (type == "kill" || type == "killwindow") { } else if (type == "kill" || type == "killwindow") {
RefCmd kill_cmd(new WindowCmd(win, &FluxboxWindow::kill)); RefCmd kill_cmd(new WindowCmd<void>(&FluxboxWindow::kill));
menu.insert(label.empty()?_FBTEXT(Windowmenu, Kill, "Kill", "Kill the window"):label.c_str(), kill_cmd); menu.insert(label.empty()?_FBTEXT(Windowmenu, Kill, "Kill", "Kill the window"):label.c_str(), kill_cmd);
} else if (type == "lower") { } else if (type == "lower") {
RefCmd lower_cmd(new WindowCmd(win, &FluxboxWindow::lower)); RefCmd lower_cmd(new WindowCmd<void>(&FluxboxWindow::lower));
menu.insert(label.empty()?_FBTEXT(Windowmenu, Lower, "Lower", "Lower the window"):label.c_str(), lower_cmd); menu.insert(label.empty()?_FBTEXT(Windowmenu, Lower, "Lower", "Lower the window"):label.c_str(), lower_cmd);
} else if (type == "raise") { } else if (type == "raise") {
RefCmd raise_cmd(new WindowCmd(win, &FluxboxWindow::raise)); RefCmd raise_cmd(new WindowCmd<void>(&FluxboxWindow::raise));
menu.insert(label.empty()?_FBTEXT(Windowmenu, Raise, "Raise", "Raise the window"):label.c_str(), raise_cmd); menu.insert(label.empty()?_FBTEXT(Windowmenu, Raise, "Raise", "Raise the window"):label.c_str(), raise_cmd);
} else if (type == "stick") { } else if (type == "stick") {
RefCmd stick_cmd(new WindowCmd(win, &FluxboxWindow::stick)); RefCmd stick_cmd(new WindowCmd<void>(&FluxboxWindow::stick));
menu.insert(label.empty()?_FBTEXT(Windowmenu, Stick, "Stick", "Stick the window"):label.c_str(), stick_cmd); 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(); else if (type == "extramenus") {
FluxboxWindow::ExtraMenus::iterator it_end = win.extraMenus().end(); 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) { for (; it != it_end; ++it) {
it->second->disableTitle(); it->second->disableTitle();
menu.insert(it->first, it->second); menu.insert(it->first, it->second);
} }
} else if (type == "sendto") { } else if (type == "sendto") {
menu.insert(label.empty()?_FBTEXT(Windowmenu, SendTo, "Send To...", "Send to menu item name"):label.c_str(), new SendToMenu(win)); menu.insert(label.empty() ? _FBTEXT(Windowmenu, SendTo, "Send To...", "Send to menu item name"):
} else if (type == "layer") { label.c_str(), new SendToMenu(*Fluxbox::instance()->findScreen(menu.screenNumber())));
}else if (type == "layer") {
BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber()); BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber());
if (screen == 0) if (screen == 0)
return false; return false;
FbTk::Menu *submenu = new LayerMenu<FluxboxWindow>(screen->menuTheme(),
class MenuContext: public LayerObject {
public:
void moveToLayer(int layer_number) {
if (WindowCmd<void>::window() == 0)
return;
WindowCmd<void>::window()->moveToLayer(layer_number);
}
int layerNumber() const {
if (WindowCmd<void>::window() == 0)
return -1;
return WindowCmd<void>::window()->layerItem().getLayerNum();
}
} static context;
FbTk::Menu *submenu = new LayerMenu(screen->menuTheme(),
screen->imageControl(), screen->imageControl(),
*screen->layerManager(). *screen->layerManager().
getLayer(Fluxbox::instance()->getMenuLayer()), getLayer(Fluxbox::instance()->getMenuLayer()),
&win, &context,
false); false);
submenu->disableTitle(); submenu->disableTitle();
menu.insert(label.empty()?_FBTEXT(Windowmenu, Layer, "Layer ...", "Layer menu"):label.c_str(), submenu); menu.insert(label.empty()?_FBTEXT(Windowmenu, Layer, "Layer ...", "Layer menu"):label.c_str(), submenu);

View file

@ -39,10 +39,11 @@ public:
static FbTk::Menu *createMenuType(const std::string &label, int screen_num); static FbTk::Menu *createMenuType(const std::string &label, int screen_num);
static bool createFromFile(const std::string &filename, FbTk::Menu &inject_into, static bool createFromFile(const std::string &filename, FbTk::Menu &inject_into,
bool require_begin); bool require_begin);
static bool createFromFile(const std::string &filename, FbTk::Menu &inject_into, static bool createWindowMenuFromFile(const std::string &filename, FbTk::Menu &inject_into,
FluxboxWindow &win, bool require_begin); bool require_begin);
static bool createWindowMenuItem(const std::string &type, const std::string &label, static bool createWindowMenuItem(const std::string &type, const std::string &label,
FbTk::Menu &inject_into, FluxboxWindow &win); FbTk::Menu &inject_into);
}; };
#endif // MENUCREATOR_HH #endif // MENUCREATOR_HH

View file

@ -31,6 +31,7 @@
#include "FbMenu.hh" #include "FbMenu.hh"
#include "FbCommands.hh" #include "FbCommands.hh"
#include "fluxbox.hh" #include "fluxbox.hh"
#include "WindowCmd.hh"
#include "FbTk/I18n.hh" #include "FbTk/I18n.hh"
#include "FbTk/StringUtil.hh" #include "FbTk/StringUtil.hh"
@ -60,53 +61,58 @@ namespace {
class RememberMenuItem : public FbTk::MenuItem { class RememberMenuItem : public FbTk::MenuItem {
public: public:
RememberMenuItem(const char *label, Remember &remember, RememberMenuItem(const char *label,
FluxboxWindow &fbwin,
Remember::Attribute attrib) : Remember::Attribute attrib) :
FbTk::MenuItem(label), m_remember(remember), FbTk::MenuItem(label),
m_win(fbwin), m_attrib(attrib) { m_attrib(attrib) {
setToggleItem(true); setToggleItem(true);
} }
bool isSelected() const { bool isSelected() const {
if (m_win.numClients()) // ensure it HAS clients if (WindowCmd<void>::window() == 0)
return m_remember.isRemembered(m_win.winClient(), m_attrib); return false;
if (WindowCmd<void>::window()->numClients()) // ensure it HAS clients
return Remember::instance().isRemembered(WindowCmd<void>::window()->winClient(), m_attrib);
else else
return false; return false;
} }
bool isEnabled() const { bool isEnabled() const {
if (WindowCmd<void>::window() == 0)
return false;
if (m_attrib != Remember::REM_JUMPWORKSPACE) if (m_attrib != Remember::REM_JUMPWORKSPACE)
return true; return true;
else if (m_win.numClients()) else if (WindowCmd<void>::window()->numClients())
return (m_remember.isRemembered(m_win.winClient(), Remember::REM_WORKSPACE)); return (Remember::instance().isRemembered(WindowCmd<void>::window()->winClient(), Remember::REM_WORKSPACE));
else else
return false; return false;
} }
void click(int button, int time) { void click(int button, int time) {
if (WindowCmd<void>::window() != 0) {
if (isSelected()) { if (isSelected()) {
m_remember.forgetAttrib(m_win.winClient(), m_attrib); Remember::instance().forgetAttrib(WindowCmd<void>::window()->winClient(), m_attrib);
} else { } else {
m_remember.rememberAttrib(m_win.winClient(), m_attrib); Remember::instance().rememberAttrib(WindowCmd<void>::window()->winClient(), m_attrib);
} }
m_remember.save(); }
Remember::instance().save();
FbTk::MenuItem::click(button, time); FbTk::MenuItem::click(button, time);
} }
private: private:
// my remember manager
Remember &m_remember;
FluxboxWindow &m_win;
Remember::Attribute m_attrib; Remember::Attribute m_attrib;
}; };
FbTk::Menu *createRememberMenu(Remember &remember, FluxboxWindow &win, bool enabled) { FbTk::Menu *createRememberMenu(BScreen &screen) {
// each fluxboxwindow has its own windowmenu // each fluxboxwindow has its own windowmenu
// so we also create a remember menu just for it... // 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, then we want this to be a unavailable menu
/*
if (!enabled) { if (!enabled) {
FbTk::MenuItem *item = new FbTk::MenuItem("unavailable"); FbTk::MenuItem *item = new FbTk::MenuItem("unavailable");
item->setEnabled(false); item->setEnabled(false);
@ -114,28 +120,28 @@ FbTk::Menu *createRememberMenu(Remember &remember, FluxboxWindow &win, bool enab
menu->updateMenu(); menu->updateMenu();
return menu; return menu;
} }
*/
_FB_USES_NLS; _FB_USES_NLS;
menu->insert(new RememberMenuItem(_FBTEXT(Remember, Workspace, "Workspace", "Remember Workspace"), 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"), 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"), 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"), 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"), 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"), 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"), 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"), 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"), 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"), 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(); menu->updateMenu();
return menu; return menu;
@ -217,16 +223,23 @@ Application::Application(bool grouped)
save_on_close_remember = false; save_on_close_remember = false;
} }
/******************************************************** /************
* Remember * * Remember *
************/ ************/
Remember *Remember::s_instance = 0;
Remember::Remember() { Remember::Remember() {
if (s_instance != 0)
throw string("Can not create more than one instance of Remember");
s_instance = this;
enableUpdate(); enableUpdate();
load(); load();
} }
Remember::~Remember() { Remember::~Remember() {
// free our resources // free our resources
// the patterns free the "Application"s // the patterns free the "Application"s
@ -245,6 +258,8 @@ Remember::~Remember() {
delete (*ait); delete (*ait);
++ait; ++ait;
} }
s_instance = 0;
} }
Application* Remember::find(WinClient &winclient) { 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 // we don't touch the window if it is a transient
// of something else // 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()) if (winclient.transientFor())
return; 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) { void Remember::updateFrameClose(FluxboxWindow &win) {
// scan all applications and remove this fbw if it is a recorded group // scan all applications and remove this fbw if it is a recorded group
Patterns::iterator it = m_pats.begin(); Patterns::iterator it = m_pats.begin();

View file

@ -384,6 +384,7 @@ void destroyAndClearList(A &a) {
BScreen::~BScreen() { BScreen::~BScreen() {
if (! managed) if (! managed)
return; return;
@ -394,6 +395,24 @@ BScreen::~BScreen() {
// we need to destroy it before we destroy workspaces // we need to destroy it before we destroy workspaces
m_workspacemenu.reset(0); 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) if (geom_pixmap != None)
imageControl().removeImage(geom_pixmap); imageControl().removeImage(geom_pixmap);
@ -601,6 +620,25 @@ FbTk::Menu *BScreen::createMenu(const std::string &label) {
return menu; 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<FbTk::Menu *>(), menu),
FbTk::Select2nd<ExtraMenus::value_type>()));
if (it != m_extramenus.end())
m_extramenus.erase(it);
// recreate window menu
m_windowmenu.reset(MenuCreator::createMenuType("windowmenu", screenNumber()));
}
void BScreen::hideMenus() { void BScreen::hideMenus() {
// hide extra menus // hide extra menus
Fluxbox::instance()->hideExtraMenus(*this); Fluxbox::instance()->hideExtraMenus(*this);
@ -684,6 +722,8 @@ void BScreen::reconfigure() {
//reconfigure menus //reconfigure menus
m_workspacemenu->reconfigure(); m_workspacemenu->reconfigure();
m_configmenu->reconfigure(); m_configmenu->reconfigure();
// recreate window menu
m_windowmenu.reset(MenuCreator::createMenuType("windowmenu", screenNumber()));
// We need to check to see if the timestamps // We need to check to see if the timestamps
// changed before we actually can restore the menus // changed before we actually can restore the menus
@ -966,6 +1006,8 @@ void BScreen::sendToWorkspace(unsigned int id, FluxboxWindow *win, bool changeWS
if (id != currentWorkspace()->workspaceID()) if (id != currentWorkspace()->workspaceID())
win->withdraw(true); win->withdraw(true);
windowMenu().hide();
reassociateWindow(win, id, true); reassociateWindow(win, id, true);
// if the window is on current workspace, show it. // if the window is on current workspace, show it.
@ -1649,9 +1691,11 @@ void BScreen::dirFocus(FluxboxWindow &win, const FocusDir dir) {
} }
void BScreen::initMenus() { void BScreen::initMenus() {
m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber())); m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber()));
m_windowmenu.reset(MenuCreator::createMenuType("windowmenu", screenNumber()));
initMenu(); initMenu();
} }
void BScreen::initMenu() { void BScreen::initMenu() {
if (m_rootmenu.get()) { if (m_rootmenu.get()) {

View file

@ -97,6 +97,7 @@ public:
typedef std::list<WinClient *> FocusedWindows; typedef std::list<WinClient *> FocusedWindows;
typedef std::vector<Workspace *> Workspaces; typedef std::vector<Workspace *> Workspaces;
typedef std::vector<std::string> WorkspaceNames; typedef std::vector<std::string> WorkspaceNames;
typedef std::list<std::pair<const char *, FbTk::Menu *> > ExtraMenus;
BScreen(FbTk::ResourceManager &rm, BScreen(FbTk::ResourceManager &rm,
const std::string &screenname, const std::string &altscreenname, const std::string &screenname, const std::string &altscreenname,
@ -123,10 +124,16 @@ public:
inline bool decorateTransient() const { return *resource.decorate_transient; } inline bool decorateTransient() const { return *resource.decorate_transient; }
inline const std::string &windowMenuFilename() const { return *resource.windowmenufile; } inline const std::string &windowMenuFilename() const { return *resource.windowmenufile; }
inline FbTk::ImageControl &imageControl() { return *m_image_control.get(); } inline FbTk::ImageControl &imageControl() { return *m_image_control.get(); }
// menus
const FbTk::Menu &getRootmenu() const { return *m_rootmenu.get(); } const FbTk::Menu &getRootmenu() const { return *m_rootmenu.get(); }
FbTk::Menu &getRootmenu() { return *m_rootmenu.get(); } FbTk::Menu &getRootmenu() { return *m_rootmenu.get(); }
const FbTk::Menu &configMenu() const { return *m_configmenu.get(); } const FbTk::Menu &configMenu() const { return *m_configmenu.get(); }
FbTk::Menu &configMenu() { 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 const std::string &getRootCommand() const { return *resource.rootcommand; }
inline ResizeModel getResizeModel() const { return *resource.resize_model; } inline ResizeModel getResizeModel() const { return *resource.resize_model; }
@ -199,6 +206,11 @@ public:
FbTk::Menu *createMenu(const std::string &label); FbTk::Menu *createMenu(const std::string &label);
void hideMenus(); 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) /// hide all windowmenus except the given one (if given)
void hideWindowMenus(const FluxboxWindow* except= 0); void hideWindowMenus(const FluxboxWindow* except= 0);
@ -393,7 +405,9 @@ private:
std::auto_ptr<FbTk::ImageControl> m_image_control; std::auto_ptr<FbTk::ImageControl> m_image_control;
std::auto_ptr<FbTk::Menu> m_configmenu, m_rootmenu, m_workspacemenu; std::auto_ptr<FbTk::Menu> m_configmenu, m_rootmenu, m_workspacemenu, m_windowmenu;
ExtraMenus m_extramenus;
typedef std::list<FbTk::Menu *> Rootmenus; typedef std::list<FbTk::Menu *> Rootmenus;
typedef std::list<Netizen *> Netizens; typedef std::list<Netizen *> Netizens;

View file

@ -28,39 +28,36 @@
#include "Screen.hh" #include "Screen.hh"
#include "fluxbox.hh" #include "fluxbox.hh"
#include "Workspace.hh" #include "Workspace.hh"
#include "WindowCmd.hh"
#include "FbTk/MultiButtonMenuItem.hh" #include "FbTk/MultiButtonMenuItem.hh"
#include "FbTk/Command.hh" #include "FbTk/Command.hh"
class SendToCmd: public FbTk::Command { class SendToCmd: public FbTk::Command {
public: public:
SendToCmd(FluxboxWindow &win, int workspace, bool follow): SendToCmd(int workspace, bool follow):
m_win(win),
m_workspace(workspace), m_workspace(workspace),
m_follow(follow) { } m_follow(follow) { }
void execute() { void execute() {
m_win.screen().sendToWorkspace(m_workspace, &m_win, m_follow); if (WindowCmd<void>::window() != 0)
WindowCmd<void>::window()->screen().sendToWorkspace(m_workspace, WindowCmd<void>::window(), m_follow);
} }
private: private:
FluxboxWindow &m_win;
const int m_workspace; const int m_workspace;
const bool m_follow; const bool m_follow;
}; };
SendToMenu::SendToMenu(FluxboxWindow &win): SendToMenu::SendToMenu(BScreen &screen):
FbMenu(win.screen().menuTheme(), FbMenu(screen.menuTheme(),
win.screen().imageControl(), screen.imageControl(),
*win.screen().layerManager().getLayer(Fluxbox::instance()->getMenuLayer())), *screen.layerManager().getLayer(Fluxbox::instance()->getMenuLayer())) {
m_win(win) {
// listen to: // listen to:
// workspace count signal // workspace count signal
// workspace names signal // workspace names signal
// current workspace signal // current workspace signal
// and window's workspace sig screen.workspaceCountSig().attach(this);
win.screen().workspaceCountSig().attach(this); screen.workspaceNamesSig().attach(this);
win.screen().workspaceNamesSig().attach(this); screen.currentWorkspaceSig().attach(this);
win.screen().currentWorkspaceSig().attach(this);
win.workspaceSig().attach(this);
disableTitle(); disableTitle();
// build menu // build menu
@ -69,19 +66,7 @@ SendToMenu::SendToMenu(FluxboxWindow &win):
void SendToMenu::update(FbTk::Subject *subj) { void SendToMenu::update(FbTk::Subject *subj) {
if (subj != 0) { if (subj != 0) {
// if workspace changed we enable all workspaces except the current one if (subj == &(theme().reconfigSig())) {
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())) {
// we got reconfig Theme signal, let base menu handle it // we got reconfig Theme signal, let base menu handle it
FbTk::Menu::update(subj); FbTk::Menu::update(subj);
return; return;
@ -91,11 +76,11 @@ void SendToMenu::update(FbTk::Subject *subj) {
// rebuild menu // rebuild menu
removeAll(); removeAll();
BScreen *screen = Fluxbox::instance()->findScreen(screenNumber());
const BScreen::Workspaces &wlist = m_win.screen().getWorkspacesList(); const BScreen::Workspaces &wlist = screen->getWorkspacesList();
for (size_t i = 0; i < wlist.size(); ++i) { for (size_t i = 0; i < wlist.size(); ++i) {
FbTk::RefCount<FbTk::Command> sendto_cmd(new SendToCmd(m_win, i, false)); FbTk::RefCount<FbTk::Command> sendto_cmd(new SendToCmd(i, false));
FbTk::RefCount<FbTk::Command> sendto_follow_cmd(new SendToCmd(m_win, i, true)); FbTk::RefCount<FbTk::Command> sendto_follow_cmd(new SendToCmd(i, true));
FbTk::MultiButtonMenuItem* item = new FbTk::MultiButtonMenuItem(3, wlist[i]->name().c_str()); FbTk::MultiButtonMenuItem* item = new FbTk::MultiButtonMenuItem(3, wlist[i]->name().c_str());
item->setCommand(1, sendto_cmd); item->setCommand(1, sendto_cmd);
@ -104,7 +89,16 @@ void SendToMenu::update(FbTk::Subject *subj) {
insert(item); insert(item);
} }
setItemEnabled(m_win.workspaceNumber(), false);
updateMenu(); updateMenu();
} }
void SendToMenu::show() {
if (WindowCmd<void>::window() != 0) {
for (unsigned int i=0; i < numberOfItems(); ++i)
setItemEnabled(i, true);
setItemEnabled(WindowCmd<void>::window()->workspaceNumber(), false);
updateMenu();
}
FbTk::Menu::show();
}

View file

@ -29,16 +29,15 @@
#include "FbTk/Observer.hh" #include "FbTk/Observer.hh"
class FluxboxWindow; class BScreen;
class SendToMenu:public FbMenu { class SendToMenu:public FbMenu {
public: public:
explicit SendToMenu(FluxboxWindow &win); explicit SendToMenu(BScreen &win);
virtual ~SendToMenu() { } virtual ~SendToMenu() { }
void show();
protected: protected:
void update(FbTk::Subject *subj); void update(FbTk::Subject *subj);
private:
FluxboxWindow &m_win;
}; };
#endif // SENDTOMENU_HH #endif // SENDTOMENU_HH

View file

@ -313,16 +313,18 @@ Slit::Slit(BScreen &scr, FbTk::XLayer &layer, const char *filename)
} }
m_layeritem.reset(new FbTk::XLayerItem(frame.window, layer)); m_layeritem.reset(new FbTk::XLayerItem(frame.window, layer));
m_layermenu.reset(new LayerMenu<Slit>(scr.menuTheme(),
m_layermenu.reset(new LayerMenu(scr.menuTheme(),
scr.imageControl(), scr.imageControl(),
*scr.layerManager(). *scr.layerManager().
getLayer(Fluxbox::instance()->getMenuLayer()), getLayer(Fluxbox::instance()->getMenuLayer()),
this, this,
true)); true));
m_layermenu->setLabel(_FBTEXT(Slit, Layer, "Slit Layer", "Title of Slit Layer Menu"));
moveToLayer((*m_rc_layernum).getNum()); 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 // Get client list for sorting purposes
loadClientList(filename); loadClientList(filename);

View file

@ -27,11 +27,15 @@
#ifndef SLIT_HH #ifndef SLIT_HH
#define SLIT_HH #define SLIT_HH
#include "Menu.hh"
#include "FbWindow.hh"
#include "Timer.hh"
#include "XLayerItem.hh"
#include "LayerMenu.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 <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
@ -47,7 +51,7 @@ class FbMenu;
class Strut; class Strut;
/// Handles dock apps /// Handles dock apps
class Slit: public FbTk::EventHandler, public FbTk::Observer { class Slit: public FbTk::EventHandler, public FbTk::Observer, public LayerObject {
public: public:
typedef std::list<SlitClient *> SlitClients; typedef std::list<SlitClient *> SlitClients;
/** /**
@ -105,7 +109,8 @@ public:
SlitTheme &theme() { return *m_slit_theme.get(); } SlitTheme &theme() { return *m_slit_theme.get(); }
const SlitTheme &theme() const { 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 isHidden() const { return m_hidden; }
inline bool doAutoHide() const { return *m_rc_auto_hide; } inline bool doAutoHide() const { return *m_rc_auto_hide; }
inline Direction direction() const { return *m_rc_direction; } inline Direction direction() const { return *m_rc_direction; }
@ -141,7 +146,7 @@ private:
SlitClients m_client_list; SlitClients m_client_list;
FbMenu m_slitmenu, m_placement_menu, m_clientlist_menu; FbMenu m_slitmenu, m_placement_menu, m_clientlist_menu;
std::auto_ptr<LayerMenu<Slit> > m_layermenu; std::auto_ptr<LayerMenu> m_layermenu;
std::string m_filename; std::string m_filename;
struct frame { struct frame {

View file

@ -51,7 +51,7 @@ public:
// force full foreground update // force full foreground update
frameWindow().updateBackground(false); frameWindow().updateBackground(false);
} }
clearWindow();
} }
}; };

View file

@ -826,7 +826,7 @@ void Toolbar::setupMenus() {
menu().insert(new BoolMenuItem(_FBTEXT(Common, MaximizeOver,"Maximize Over", "Maximize over this thing when maximizing"), menu().insert(new BoolMenuItem(_FBTEXT(Common, MaximizeOver,"Maximize Over", "Maximize over this thing when maximizing"),
*m_rc_maximize_over, *m_rc_maximize_over,
reconfig_toolbar_and_save_resource)); 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());

View file

@ -31,6 +31,7 @@
#include "LayerMenu.hh" #include "LayerMenu.hh"
#include "ToolFactory.hh" #include "ToolFactory.hh"
#include "ToolTheme.hh" #include "ToolTheme.hh"
#include "fluxbox.hh"
#include "FbTk/Timer.hh" #include "FbTk/Timer.hh"
#include "FbTk/Resource.hh" #include "FbTk/Resource.hh"
@ -54,7 +55,7 @@ class ImageControl;
/// The toolbar. /// The toolbar.
/// Handles iconbar, workspace name view and clock view /// 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: public:
/// Toolbar placement on the screen /// Toolbar placement on the screen
@ -101,15 +102,15 @@ public:
void update(FbTk::Subject *subj); void update(FbTk::Subject *subj);
FbTk::XLayerItem &layerItem() { return m_layeritem; } int layerNumber() const { return const_cast<FbTk::XLayerItem &>(m_layeritem).getLayerNum(); }
inline const FbTk::Menu &menu() const { return m_toolbarmenu; } inline const FbTk::Menu &menu() const { return m_toolbarmenu; }
inline FbTk::Menu &menu() { return m_toolbarmenu; } inline FbTk::Menu &menu() { return m_toolbarmenu; }
inline FbTk::Menu &placementMenu() { return m_placementmenu; } inline FbTk::Menu &placementMenu() { return m_placementmenu; }
inline const FbTk::Menu &placementMenu() const { return m_placementmenu; } inline const FbTk::Menu &placementMenu() const { return m_placementmenu; }
inline FbTk::Menu &layermenu() { return m_layermenu; } inline FbTk::Menu &layerMenu() { return m_layermenu; }
inline const FbTk::Menu &layermenu() const { return m_layermenu; } inline const FbTk::Menu &layerMenu() const { return m_layermenu; }
/// are we hidden? /// are we hidden?
inline bool isHidden() const { return m_hidden; } inline bool isHidden() const { return m_hidden; }
@ -163,7 +164,7 @@ private:
FbTk::Timer m_hide_timer; ///< timer to for auto hide toolbar FbTk::Timer m_hide_timer; ///< timer to for auto hide toolbar
FbTk::XLayerItem m_layeritem; ///< layer item, must be declared before layermenu FbTk::XLayerItem m_layeritem; ///< layer item, must be declared before layermenu
LayerMenu<Toolbar> m_layermenu; LayerMenu m_layermenu;
FbMenu m_placementmenu, m_toolbarmenu; FbMenu m_placementmenu, m_toolbarmenu;

View file

@ -36,6 +36,7 @@
#include "FbWinFrame.hh" #include "FbWinFrame.hh"
#include "WinButton.hh" #include "WinButton.hh"
#include "WinButtonTheme.hh" #include "WinButtonTheme.hh"
#include "WindowCmd.hh"
#include "Remember.hh" #include "Remember.hh"
#include "MenuCreator.hh" #include "MenuCreator.hh"
@ -294,7 +295,6 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbWinFrameTheme &tm,
m_attaching_tab(0), m_attaching_tab(0),
m_screen(client.screen()), m_screen(client.screen()),
display(FbTk::App::instance()->display()), display(FbTk::App::instance()->display()),
m_windowmenu(MenuCreator::createMenu("", client.screenNumber())),
m_button_grab_x(0), m_button_grab_y(0), m_button_grab_x(0), m_button_grab_y(0),
m_last_move_x(0), m_last_move_y(0), m_last_move_x(0), m_last_move_y(0),
m_last_resize_h(1), m_last_resize_w(1), m_last_resize_h(1), m_last_resize_w(1),
@ -323,6 +323,9 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbWinFrameTheme &tm,
FluxboxWindow::~FluxboxWindow() { FluxboxWindow::~FluxboxWindow() {
if (WindowCmd<void>::window() == this)
WindowCmd<void>::setWindow(0);
#ifdef DEBUG #ifdef DEBUG
cerr<<__FILE__<<"("<<__LINE__<<"): starting ~FluxboxWindow("<<this<<", "<<title()<<")"<<endl; cerr<<__FILE__<<"("<<__LINE__<<"): starting ~FluxboxWindow("<<this<<", "<<title()<<")"<<endl;
cerr<<__FILE__<<"("<<__LINE__<<"): num clients = "<<numClients()<<endl; cerr<<__FILE__<<"("<<__LINE__<<"): num clients = "<<numClients()<<endl;
@ -364,24 +367,6 @@ FluxboxWindow::~FluxboxWindow() {
} }
// deal with extra menus // deal with extra menus
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);
}
}
#ifdef DEBUG #ifdef DEBUG
cerr<<__FILE__<<"("<<__LINE__<<"): ~FluxboxWindow("<<this<<")"<<endl; cerr<<__FILE__<<"("<<__LINE__<<"): ~FluxboxWindow("<<this<<")"<<endl;
#endif // DEBUG #endif // DEBUG
@ -2263,7 +2248,7 @@ void FluxboxWindow::showMenu(int menu_x, int menu_y) {
else if (menu_x + static_cast<signed>(menu().width()) >= static_cast<signed>(screen().maxRight(head))) else if (menu_x + static_cast<signed>(menu().width()) >= static_cast<signed>(screen().maxRight(head)))
menu_x = screen().maxRight(head) - menu().width() - 1; menu_x = screen().maxRight(head) - menu().width() - 1;
WindowCmd<void>::setWindow(this);
menu().move(menu_x, menu_y); menu().move(menu_x, menu_y);
menu().show(); menu().show();
menu().raise(); menu().raise();
@ -2275,6 +2260,8 @@ void FluxboxWindow::showMenu(int menu_x, int menu_y) {
if it's already visible it'll be hidden if it's already visible it'll be hidden
*/ */
void FluxboxWindow::popupMenu() { void FluxboxWindow::popupMenu() {
WindowCmd<void>::setWindow(this);
if (menu().isVisible()) { if (menu().isVisible()) {
menu().hide(); menu().hide();
return; return;
@ -3553,6 +3540,14 @@ const FbTk::FbWindow &FluxboxWindow::fbWindow() const {
return frame().window(); return frame().window();
} }
FbTk::Menu &FluxboxWindow::menu() {
return screen().windowMenu();
}
const FbTk::Menu &FluxboxWindow::menu() const {
return screen().windowMenu();
}
unsigned int FluxboxWindow::titlebarHeight() const { unsigned int FluxboxWindow::titlebarHeight() const {
return frame().titlebarHeight(); return frame().titlebarHeight();
} }
@ -3736,24 +3731,6 @@ void FluxboxWindow::sendConfigureNotify(bool send_to_netizens) {
} // end for } // 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 *>(), menu),
Select2nd<ExtraMenus::value_type>()));
if (it != m_extramenus.end())
m_extramenus.erase(it);
setupMenu();
}
void FluxboxWindow::close() { void FluxboxWindow::close() {
if (m_client) if (m_client)
@ -3870,33 +3847,6 @@ void FluxboxWindow::setupWindow() {
// end setup frame // 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
} }

View file

@ -31,7 +31,6 @@
#include "FbTk/Subject.hh" #include "FbTk/Subject.hh"
#include "FbTk/EventHandler.hh" #include "FbTk/EventHandler.hh"
#include "FbTk/XLayerItem.hh" #include "FbTk/XLayerItem.hh"
#include "FbWinFrame.hh" #include "FbWinFrame.hh"
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -153,8 +152,6 @@ public:
} BlackboxAttributes; } BlackboxAttributes;
typedef std::list<WinClient *> ClientList; typedef std::list<WinClient *> ClientList;
// this should perhaps be a refcount??
typedef std::list<std::pair<const char *, FbTk::Menu *> > ExtraMenus;
/// create a window from a client /// create a window from a client
FluxboxWindow(WinClient &client, FluxboxWindow(WinClient &client,
@ -322,18 +319,8 @@ public:
FbTk::FbWindow &fbWindow(); FbTk::FbWindow &fbWindow();
const FbTk::FbWindow &fbWindow() const; const FbTk::FbWindow &fbWindow() const;
FbTk::Menu &menu() { return *m_windowmenu.get(); } FbTk::Menu &menu();
const FbTk::Menu &menu() const { return *m_windowmenu.get(); } const FbTk::Menu &menu() const;
// 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; }
const FbTk::FbWindow &parent() const { return m_parent; } const FbTk::FbWindow &parent() const { return m_parent; }
FbTk::FbWindow &parent() { return m_parent; } FbTk::FbWindow &parent() { return m_parent; }
@ -398,7 +385,6 @@ private:
static const int PropBlackboxAttributesElements = 8; static const int PropBlackboxAttributesElements = 8;
void setupWindow(); void setupWindow();
void setupMenu();
void init(); void init();
/// applies a shape mask to the window if it has one /// applies a shape mask to the window if it has one
@ -474,8 +460,6 @@ private:
Display *display; /// display connection Display *display; /// display connection
BlackboxAttributes m_blackbox_attrib; BlackboxAttributes m_blackbox_attrib;
std::auto_ptr<FbTk::Menu> m_windowmenu;
timeval m_last_focus_time; timeval m_last_focus_time;
int m_button_grab_x, m_button_grab_y; // handles last button press event for move 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; ResizeCorner m_resize_corner;
ExtraMenus m_extramenus;
static int s_num_grabs; ///< number of XGrabPointer's static int s_num_grabs; ///< number of XGrabPointer's
}; };

View file

@ -31,6 +31,7 @@
#include "Window.hh" #include "Window.hh"
#include "WinClient.hh" #include "WinClient.hh"
#include "FbWinFrame.hh" #include "FbWinFrame.hh"
#include "WindowCmd.hh"
#include "FbTk/I18n.hh" #include "FbTk/I18n.hh"
#include "FbTk/MenuItem.hh" #include "FbTk/MenuItem.hh"
@ -83,10 +84,18 @@ int countTransients(const WinClient &client) {
class ClientMenuItem:public FbTk::MenuItem { class ClientMenuItem:public FbTk::MenuItem {
public: public:
ClientMenuItem(WinClient &client): 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) { m_client(client) {
} }
FbTk::Menu *submenu() { return &m_client.screen().windowMenu(); }
const FbTk::Menu *submenu() const { return &m_client.screen().windowMenu(); }
void showSubmenu() {
WindowCmd<void>::setWindow(m_client.fbwindow());
FbTk::MenuItem::showSubmenu();
}
void click(int button, int time) { void click(int button, int time) {
if (m_client.fbwindow() == 0) if (m_client.fbwindow() == 0)
return; return;