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
#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 <typename ItemType>
class LayerMenuItem : public FbTk::MenuItem {
public:
LayerMenuItem(const char *label, ItemType *object, int layernum,
LayerMenuItem(const char *label, LayerObject *object, int layernum,
FbTk::RefCount<FbTk::Command> &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 <typename ItemType>
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 <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

View file

@ -29,6 +29,7 @@
#include "fluxbox.hh"
#include "CommandParser.hh"
#include "Window.hh"
#include "WindowCmd.hh"
#include "FbMenu.hh"
#include "IconMenu.hh"
@ -53,11 +54,6 @@
#include <iostream>
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,
const std::string &directory) {
// 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);
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,
bool MenuCreator::createWindowMenuFromFile(const std::string &filename,
FbTk::Menu &inject_into,
FluxboxWindow &win, bool require_begin) {
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<FbTk::Command> RefCmd;
typedef FbTk::SimpleCommand<FluxboxWindow> WindowCmd;
_FB_USES_NLS;
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);
} 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<void>(&FluxboxWindow::maximizeFull));
RefCmd maximize_vert_cmd(new WindowCmd<void>(&FluxboxWindow::maximizeVertical));
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());
// create maximize item with:
// button1: Maximize normal
// button2: Maximize Vertical
@ -471,42 +497,60 @@ 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<void>(&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<void>(&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<void>(&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<void>(&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<void>(&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<void>(&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<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->layerManager().
getLayer(Fluxbox::instance()->getMenuLayer()),
&win,
&context,
false);
submenu->disableTitle();
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 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

View file

@ -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<void>::window() == 0)
return false;
if (WindowCmd<void>::window()->numClients()) // ensure it HAS clients
return Remember::instance().isRemembered(WindowCmd<void>::window()->winClient(), m_attrib);
else
return false;
}
bool isEnabled() const {
if (WindowCmd<void>::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<void>::window()->numClients())
return (Remember::instance().isRemembered(WindowCmd<void>::window()->winClient(), Remember::REM_WORKSPACE));
else
return false;
}
void click(int button, int time) {
if (WindowCmd<void>::window() != 0) {
if (isSelected()) {
m_remember.forgetAttrib(m_win.winClient(), m_attrib);
Remember::instance().forgetAttrib(WindowCmd<void>::window()->winClient(), m_attrib);
} 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);
}
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();

View file

@ -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<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() {
// 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
@ -966,6 +1006,8 @@ void BScreen::sendToWorkspace(unsigned int id, FluxboxWindow *win, bool changeWS
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()) {

View file

@ -97,6 +97,7 @@ public:
typedef std::list<WinClient *> FocusedWindows;
typedef std::vector<Workspace *> Workspaces;
typedef std::vector<std::string> WorkspaceNames;
typedef std::list<std::pair<const char *, FbTk::Menu *> > 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<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<Netizen *> Netizens;

View file

@ -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<void>::window() != 0)
WindowCmd<void>::window()->screen().sendToWorkspace(m_workspace, WindowCmd<void>::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<FbTk::Command> sendto_cmd(new SendToCmd(m_win, i, false));
FbTk::RefCount<FbTk::Command> sendto_follow_cmd(new SendToCmd(m_win, i, true));
FbTk::RefCount<FbTk::Command> sendto_cmd(new SendToCmd(i, false));
FbTk::RefCount<FbTk::Command> 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<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"
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

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_layermenu.reset(new LayerMenu<Slit>(scr.menuTheme(),
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);

View file

@ -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 <X11/Xlib.h>
#include <X11/Xutil.h>
@ -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<SlitClient *> 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<LayerMenu<Slit> > m_layermenu;
std::auto_ptr<LayerMenu> m_layermenu;
std::string m_filename;
struct frame {

View file

@ -51,7 +51,7 @@ public:
// force full foreground update
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"),
*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());

View file

@ -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<FbTk::XLayerItem &>(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,7 +164,7 @@ private:
FbTk::Timer m_hide_timer; ///< timer to for auto hide toolbar
FbTk::XLayerItem m_layeritem; ///< layer item, must be declared before layermenu
LayerMenu<Toolbar> m_layermenu;
LayerMenu m_layermenu;
FbMenu m_placementmenu, m_toolbarmenu;

View file

@ -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<void>::window() == this)
WindowCmd<void>::setWindow(0);
#ifdef DEBUG
cerr<<__FILE__<<"("<<__LINE__<<"): starting ~FluxboxWindow("<<this<<", "<<title()<<")"<<endl;
cerr<<__FILE__<<"("<<__LINE__<<"): num clients = "<<numClients()<<endl;
@ -364,24 +367,6 @@ FluxboxWindow::~FluxboxWindow() {
}
// 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
cerr<<__FILE__<<"("<<__LINE__<<"): ~FluxboxWindow("<<this<<")"<<endl;
#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)))
menu_x = screen().maxRight(head) - menu().width() - 1;
WindowCmd<void>::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<void>::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 *>(), menu),
Select2nd<ExtraMenus::value_type>()));
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
}

View file

@ -31,7 +31,6 @@
#include "FbTk/Subject.hh"
#include "FbTk/EventHandler.hh"
#include "FbTk/XLayerItem.hh"
#include "FbWinFrame.hh"
#include <X11/Xlib.h>
@ -153,8 +152,6 @@ public:
} BlackboxAttributes;
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
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<FbTk::Menu> 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
};

View file

@ -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<void>::setWindow(m_client.fbwindow());
FbTk::MenuItem::showSubmenu();
}
void click(int button, int time) {
if (m_client.fbwindow() == 0)
return;