Refactor: split out menu generation from BScreen

Again, it's easier to read the code when the whole menu-generation is out of
the way.
This commit is contained in:
Mathias Gumz 2015-01-15 18:49:35 +01:00
parent 8387742c88
commit bd9afcafb9
7 changed files with 573 additions and 382 deletions

333
src/ConfigMenu.cc Normal file
View file

@ -0,0 +1,333 @@
// ConfigMenu.cc for Fluxbox Window Manager
// Copyright (c) 2015 - Mathias Gumz <akira@fluxbox.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include "ConfigMenu.hh"
#include "Screen.hh"
#include "fluxbox.hh"
#include "FocusModelMenuItem.hh"
#include "ScreenPlacement.hh"
#include "FbMenu.hh"
#include "FbTk/Menu.hh"
#include "FbTk/BoolMenuItem.hh"
#include "FbTk/IntMenuItem.hh"
#include "FbTk/MenuSeparator.hh"
#include "FbTk/RadioMenuItem.hh"
#include "FbTk/MacroCommand.hh"
#include "FbTk/CommandParser.hh"
#include "FbTk/SimpleCommand.hh"
#include "FbTk/Transparent.hh"
#include "FbTk/Resource.hh"
#include "FbTk/I18n.hh"
namespace {
class TabPlacementMenuItem: public FbTk::RadioMenuItem {
public:
TabPlacementMenuItem(const FbTk::FbString & label, BScreen &screen,
FbWinFrame::TabPlacement place,
FbTk::RefCount<FbTk::Command<void> > &cmd):
FbTk::RadioMenuItem(label, cmd),
m_screen(screen),
m_place(place) {
setCloseOnClick(false);
}
bool isSelected() const { return m_screen.getTabPlacement() == m_place; }
void click(int button, int time, unsigned int mods) {
m_screen.saveTabPlacement(m_place);
FbTk::RadioMenuItem::click(button, time, mods);
}
private:
BScreen &m_screen;
FbWinFrame::TabPlacement m_place;
};
typedef FbTk::RefCount<FbTk::Command<void> > _Cmd;
enum {
L_ALPHA = 0,
L_PSEUDO_TRANS,
L_FOCUS_ALPHA,
L_UNFOCUS_ALPHA,
L_MENU_ALPHA,
};
void setupAlphaMenu(FbTk::Menu& parent, ConfigMenu::SetupHelper& sh, _Cmd& save_reconf) {
#ifdef HAVE_XRENDER
_FB_USES_NLS;
static const FbTk::FbString _labels[] = {
_FB_XTEXT(Configmenu, Transparency, "Transparency", "Menu containing various transparency options"),
_FB_XTEXT(Configmenu, ForcePseudoTrans, "Force Pseudo-Transparency", "When composite is available, still use old pseudo-transparency"),
_FB_XTEXT(Configmenu, FocusedAlpha, "Focused Window Alpha", "Transparency level of the focused window"),
_FB_XTEXT(Configmenu, UnfocusedAlpha, "Unfocused Window Alpha", "Transparency level of unfocused windows"),
_FB_XTEXT(Configmenu, MenuAlpha, "Menu Alpha", "Transparency level of menu")
};
FbTk::FbString label = _labels[L_ALPHA];
FbTk::Menu* menu = sh.screen.createMenu(label);
if (FbTk::Transparent::haveComposite(true)) {
static FbTk::SimpleAccessor<bool> s_pseudo = Fluxbox::instance()->getPseudoTrans();
menu->insertItem(new FbTk::BoolMenuItem(_labels[L_PSEUDO_TRANS], s_pseudo, save_reconf));
}
// in order to save system resources, don't save or reconfigure alpha
// settings until after the user is done changing them
_Cmd delayed_save_and_reconf(new FbTk::DelayedCmd(save_reconf));
FbTk::MenuItem *focused_alpha_item =
new FbTk::IntMenuItem(_labels[L_FOCUS_ALPHA], sh.resource.focused_alpha, 0, 255, *menu);
focused_alpha_item->setCommand(delayed_save_and_reconf);
menu->insertItem(focused_alpha_item);
FbTk::MenuItem *unfocused_alpha_item =
new FbTk::IntMenuItem(_labels[L_UNFOCUS_ALPHA], sh.resource.unfocused_alpha, 0, 255, *menu);
unfocused_alpha_item->setCommand(delayed_save_and_reconf);
menu->insertItem(unfocused_alpha_item);
FbTk::MenuItem *menu_alpha_item =
new FbTk::IntMenuItem(_labels[L_MENU_ALPHA], sh.resource.menu_alpha, 0, 255, *menu);
menu_alpha_item->setCommand(delayed_save_and_reconf);
menu->insertItem(menu_alpha_item);
menu->updateMenu();
parent.insertSubmenu(label, menu);
#endif
}
#define _BOOLITEM(m,a, b, c, d, e, f) (m).insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(a, b, c, d), e, f))
void setupFocusMenu(FbTk::Menu& menu, ConfigMenu::SetupHelper& sh, _Cmd& save_rc, _Cmd& save_reconf) {
_FB_USES_NLS;
// we don't set this to internal menu so will
// be deleted toghether with the parent
FbTk::FbString label = _FB_XTEXT(Configmenu, FocusModel, "Focus Model", "Method used to give focus to windows");
FbMenu* fm = sh.screen.createMenu(label);
#define _FOCUSITEM(a, b, c, d, e) \
fm->insertItem(new FocusModelMenuItem(_FB_XTEXT(a, b, c, d), sh.screen.focusControl(), \
e, save_reconf))
_FOCUSITEM(Configmenu, ClickFocus,
"Click To Focus", "Click to focus",
FocusControl::CLICKFOCUS);
_FOCUSITEM(Configmenu, MouseFocus,
"Mouse Focus (Keyboard Friendly)",
"Mouse Focus (Keyboard Friendly)",
FocusControl::MOUSEFOCUS);
_FOCUSITEM(Configmenu, StrictMouseFocus,
"Mouse Focus (Strict)",
"Mouse Focus (Strict)",
FocusControl::STRICTMOUSEFOCUS);
#undef _FOCUSITEM
fm->insertItem(new FbTk::MenuSeparator());
fm->insertItem(new TabFocusModelMenuItem(_FB_XTEXT(Configmenu,
ClickTabFocus, "ClickTabFocus", "Click tab to focus windows"),
sh.screen.focusControl(), FocusControl::CLICKTABFOCUS, save_reconf));
fm->insertItem(new TabFocusModelMenuItem(_FB_XTEXT(Configmenu,
MouseTabFocus, "MouseTabFocus", "Hover over tab to focus windows"),
sh.screen.focusControl(), FocusControl::MOUSETABFOCUS, save_reconf));
fm->insertItem(new FbTk::MenuSeparator());
try {
fm->insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(Configmenu, FocusNew,
"Focus New Windows", "Focus newly created windows"),
sh.rm.getResource<bool>(sh.screen.name() + ".focusNewWindows"),
save_rc));
} catch (FbTk::ResourceException & e) {
std::cerr<<e.what()<<std::endl;
}
#ifdef XINERAMA
try {
fm->insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(Configmenu, FocusSameHead,
"Keep Head", "Only revert focus on same head"),
sh.rm.getResource<bool>(sh.screen.name() + ".focusSameHead"),
save_rc));
} catch (FbTk::ResourceException e) {
std::cerr << e.what() << std::endl;
}
#endif // XINERAMA
_BOOLITEM(*fm, Configmenu, AutoRaise,
"Auto Raise", "Auto Raise windows on sloppy",
sh.resource.auto_raise, save_rc);
_BOOLITEM(*fm, Configmenu, ClickRaises,
"Click Raises", "Click Raises",
sh.resource.click_raises, save_rc);
fm->updateMenu();
menu.insertSubmenu(label, fm);
}
void setupMaximizeMenu(FbTk::Menu& menu, ConfigMenu::SetupHelper& sh, _Cmd& save_rc) {
_FB_USES_NLS;
FbTk::FbString label = _FB_XTEXT(Configmenu, MaxMenu,
"Maximize Options", "heading for maximization options");
FbTk::Menu* mm = sh.screen.createMenu(label);
_BOOLITEM(*mm, Configmenu, FullMax,
"Full Maximization", "Maximise over slit, toolbar, etc",
sh.resource.full_max, save_rc);
_BOOLITEM(*mm, Configmenu, MaxIgnoreInc,
"Ignore Resize Increment",
"Maximizing Ignores Resize Increment (e.g. xterm)",
sh.resource.max_ignore_inc, save_rc);
_BOOLITEM(*mm, Configmenu, MaxDisableMove,
"Disable Moving", "Don't Allow Moving While Maximized",
sh.resource.max_disable_move, save_rc);
_BOOLITEM(*mm, Configmenu, MaxDisableResize,
"Disable Resizing", "Don't Allow Resizing While Maximized",
sh.resource.max_disable_resize, save_rc);
mm->updateMenu();
menu.insertSubmenu(label, mm);
}
void setupTabMenu(FbTk::Menu& parent, ConfigMenu::SetupHelper& sh, _Cmd& save_reconf, _Cmd& save_reconftabs) {
_FB_USES_NLS;
FbTk::FbString label = _FB_XTEXT(Configmenu, TabMenu, "Tab Options", "heading for tab-related options");
// TODO: main-category is 'Menu'?? should be 'ConfigMenu'???
FbTk::FbString p_label = _FB_XTEXT(Menu, Placement, "Placement", "Title of Placement menu");
FbTk::Menu* menu = sh.screen.createMenu(label);
FbTk::Menu* p_menu = sh.screen.createToggleMenu(p_label);
menu->insertSubmenu(p_label, p_menu);
menu->insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(Configmenu, TabsInTitlebar,
"Tabs in Titlebar", "Tabs in Titlebar"),
sh.resource.default_internal_tabs, save_reconftabs));
menu->insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(Common, MaximizeOver,
"Maximize Over", "Maximize over this thing when maximizing"),
sh.resource.max_over_tabs, save_reconf));
menu->insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(Toolbar, ShowIcons,
"Show Pictures", "chooses if little icons are shown next to title in the iconbar"),
sh.resource.tabs_use_pixmap, save_reconf));
FbTk::MenuItem *tab_width_item =
new FbTk::IntMenuItem(_FB_XTEXT(Configmenu, ExternalTabWidth,
"External Tab Width",
"Width of external-style tabs"),
sh.resource.tab_width, 10, 3000, /* silly number */
*menu);
tab_width_item->setCommand(save_reconftabs);
menu->insertItem(tab_width_item);
// menu is 3 wide, 5 down
struct PlacementP {
const FbTk::FbString label;
FbWinFrame::TabPlacement placement;
};
static const PlacementP place_menu[] = {
{ _FB_XTEXT(Align, TopLeft, "Top Left", "Top Left"), FbWinFrame::TOPLEFT},
{ _FB_XTEXT(Align, LeftTop, "Left Top", "Left Top"), FbWinFrame::LEFTTOP},
{ _FB_XTEXT(Align, LeftCenter, "Left Center", "Left Center"), FbWinFrame::LEFT},
{ _FB_XTEXT(Align, LeftBottom, "Left Bottom", "Left Bottom"), FbWinFrame::LEFTBOTTOM},
{ _FB_XTEXT(Align, BottomLeft, "Bottom Left", "Bottom Left"), FbWinFrame::BOTTOMLEFT},
{ _FB_XTEXT(Align, TopCenter, "Top Center", "Top Center"), FbWinFrame::TOP},
{ "", FbWinFrame::TOPLEFT},
{ "", FbWinFrame::TOPLEFT},
{ "", FbWinFrame::TOPLEFT},
{ _FB_XTEXT(Align, BottomCenter, "Bottom Center", "Bottom Center"), FbWinFrame::BOTTOM},
{ _FB_XTEXT(Align, TopRight, "Top Right", "Top Right"), FbWinFrame::TOPRIGHT},
{ _FB_XTEXT(Align, RightTop, "Right Top", "Right Top"), FbWinFrame::RIGHTTOP},
{ _FB_XTEXT(Align, RightCenter, "Right Center", "Right Center"), FbWinFrame::RIGHT},
{ _FB_XTEXT(Align, RightBottom, "Right Bottom", "Right Bottom"), FbWinFrame::RIGHTBOTTOM},
{ _FB_XTEXT(Align, BottomRight, "Bottom Right", "Bottom Right"), FbWinFrame::BOTTOMRIGHT}
};
p_menu->setMinimumColumns(3);
// create items in sub menu
for (size_t i=0; i< sizeof(place_menu)/sizeof(PlacementP); ++i) {
const PlacementP& p = place_menu[i];
if (p.label == "") {
p_menu->insert(p.label);
p_menu->setItemEnabled(i, false);
} else
p_menu->insertItem(new TabPlacementMenuItem(p.label,
sh.screen, p.placement, save_reconftabs));
}
p_menu->updateMenu();
parent.insertSubmenu(label, menu);
}
}
void ConfigMenu::setup(FbTk::Menu& menu, ConfigMenu::SetupHelper& sh) {
_FB_USES_NLS;
FbTk::MacroCommand *s_a_reconf_macro = new FbTk::MacroCommand();
FbTk::MacroCommand *s_a_reconftabs_macro = new FbTk::MacroCommand();
_Cmd saverc_cmd(new FbTk::SimpleCommand<Fluxbox>( *Fluxbox::instance(), &Fluxbox::save_rc));
_Cmd reconf_cmd(FbTk::CommandParser<void>::instance().parse("reconfigure"));
_Cmd reconftabs_cmd(new FbTk::SimpleCommand<BScreen>(sh.screen, &BScreen::reconfigureTabs));
s_a_reconf_macro->add(saverc_cmd);
s_a_reconf_macro->add(reconf_cmd);
s_a_reconftabs_macro->add(saverc_cmd);
s_a_reconftabs_macro->add(reconftabs_cmd);
_Cmd save_and_reconfigure(s_a_reconf_macro);
_Cmd save_and_reconftabs(s_a_reconftabs_macro);
setupFocusMenu(menu, sh, saverc_cmd, save_and_reconfigure);
setupMaximizeMenu(menu, sh, saverc_cmd);
setupTabMenu(menu, sh, save_and_reconfigure, save_and_reconftabs);
#ifdef HAVE_XRENDER
if (FbTk::Transparent::haveRender() ||
FbTk::Transparent::haveComposite()) {
setupAlphaMenu(menu, sh, save_and_reconfigure);
}
#endif // HAVE_XRENDER
_BOOLITEM(menu, Configmenu, OpaqueMove,
"Opaque Window Moving",
"Window Moving with whole window visible (as opposed to outline moving)",
sh.resource.opaque_move, saverc_cmd);
_BOOLITEM(menu, Configmenu, WorkspaceWarping,
"Workspace Warping",
"Workspace Warping - dragging windows to the edge and onto the next workspace",
sh.resource.workspace_warping, saverc_cmd);
#undef _BOOLITEM
menu.updateMenu();
}

47
src/ConfigMenu.hh Normal file
View file

@ -0,0 +1,47 @@
#ifndef CONFIG_MENU_HH
#define CONFIG_MENU_HH
// ConfigMenu.cc for Fluxbox Window Manager
// Copyright (c) 2015 - Mathias Gumz <akira@fluxbox.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
class BScreen;
class ScreenResource;
namespace FbTk{
class Menu;
class ResourceManager;
}
class ConfigMenu {
public:
// makes the setup() function-signature shorter
struct SetupHelper {
BScreen& screen;
FbTk::ResourceManager& rm;
ScreenResource& resource;
};
static void setup(FbTk::Menu& menu, SetupHelper& sh);
};
#endif

View file

@ -171,6 +171,8 @@ fluxbox_SOURCES = \
src/ColSmartPlacement.hh \
src/CommandDialog.cc \
src/CommandDialog.hh \
src/ConfigMenu.hh \
src/ConfigMenu.cc \
src/CurrentWindowCmd.cc \
src/CurrentWindowCmd.hh \
src/Debug.hh \
@ -225,6 +227,8 @@ fluxbox_SOURCES = \
src/Screen.hh \
src/ScreenPlacement.cc \
src/ScreenPlacement.hh \
src/ScreenResource.cc \
src/ScreenResource.hh \
src/SendToMenu.cc \
src/SendToMenu.hh \
src/Strut.hh \

View file

@ -42,6 +42,7 @@
#include "FbTk/RadioMenuItem.hh"
// menus
#include "ConfigMenu.hh"
#include "FbMenu.hh"
#include "LayerMenu.hh"
@ -173,55 +174,11 @@ int anotherWMRunning(Display *display, XErrorEvent *) {
int calcSquareDistance(int x1, int y1, int x2, int y2) {
return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
}
class TabPlacementMenuItem: public FbTk::RadioMenuItem {
public:
TabPlacementMenuItem(const FbTk::FbString & label, BScreen &screen,
FbWinFrame::TabPlacement place,
FbTk::RefCount<FbTk::Command<void> > &cmd):
FbTk::RadioMenuItem(label, cmd),
m_screen(screen),
m_place(place) {
setCloseOnClick(false);
}
bool isSelected() const { return m_screen.getTabPlacement() == m_place; }
void click(int button, int time, unsigned int mods) {
m_screen.saveTabPlacement(m_place);
FbTk::RadioMenuItem::click(button, time, mods);
}
private:
BScreen &m_screen;
FbWinFrame::TabPlacement m_place;
};
void clampMenuDelay(int& delay) {
delay = FbTk::Util::clamp(delay, 0, 5000);
}
struct TabPlacementString {
FbWinFrame::TabPlacement placement;
const char* str;
};
const TabPlacementString placement_strings[] = {
{ FbWinFrame::TOPLEFT, "TopLeft" },
{ FbWinFrame::TOP, "Top" },
{ FbWinFrame::TOPRIGHT, "TopRight" },
{ FbWinFrame::BOTTOMLEFT, "BottomLeft" },
{ FbWinFrame::BOTTOM, "Bottom" },
{ FbWinFrame::BOTTOMRIGHT, "BottomRight" },
{ FbWinFrame::LEFTBOTTOM, "LeftBottom" },
{ FbWinFrame::LEFT, "Left" },
{ FbWinFrame::LEFTTOP, "LeftTop" },
{ FbWinFrame::RIGHTBOTTOM, "RightBottom" },
{ FbWinFrame::RIGHT, "Right" },
{ FbWinFrame::RIGHTTOP, "RightTop" }
};
Atom atom_fbcmd = 0;
Atom atom_wm_check = 0;
Atom atom_net_desktop = 0;
@ -238,72 +195,10 @@ void initAtoms(Display* dpy) {
atom_kwm1 = XInternAtom(dpy, "KWM_DOCKWINDOW", False);
}
} // end anonymous namespace
namespace FbTk {
template<>
string FbTk::Resource<FbWinFrame::TabPlacement>::
getString() const {
size_t i = (m_value == FbTk::Util::clamp(m_value, FbWinFrame::TOPLEFT, FbWinFrame::RIGHTTOP)
? m_value
: FbWinFrame::DEFAULT) - 1;
return placement_strings[i].str;
}
template<>
void FbTk::Resource<FbWinFrame::TabPlacement>::
setFromString(const char *strval) {
size_t i;
for (i = 0; i < sizeof(placement_strings)/sizeof(TabPlacementString); ++i) {
if (strcasecmp(strval, placement_strings[i].str) == 0) {
m_value = placement_strings[i].placement;
return;
}
}
setDefaultValue();
}
} // end namespace FbTk
BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
const string &scrname,
const string &altscrname):
opaque_move(rm, true, scrname + ".opaqueMove", altscrname+".OpaqueMove"),
full_max(rm, false, scrname+".fullMaximization", altscrname+".FullMaximization"),
max_ignore_inc(rm, true, scrname+".maxIgnoreIncrement", altscrname+".MaxIgnoreIncrement"),
max_disable_move(rm, false, scrname+".maxDisableMove", altscrname+".MaxDisableMove"),
max_disable_resize(rm, false, scrname+".maxDisableResize", altscrname+".MaxDisableResize"),
workspace_warping(rm, true, scrname+".workspacewarping", altscrname+".WorkspaceWarping"),
show_window_pos(rm, false, scrname+".showwindowposition", altscrname+".ShowWindowPosition"),
auto_raise(rm, true, scrname+".autoRaise", altscrname+".AutoRaise"),
click_raises(rm, true, scrname+".clickRaises", altscrname+".ClickRaises"),
default_deco(rm, "NORMAL", scrname+".defaultDeco", altscrname+".DefaultDeco"),
tab_placement(rm, FbWinFrame::TOPLEFT, scrname+".tab.placement", altscrname+".Tab.Placement"),
windowmenufile(rm, Fluxbox::instance()->getDefaultDataFilename("windowmenu"), scrname+".windowMenu", altscrname+".WindowMenu"),
typing_delay(rm, 0, scrname+".noFocusWhileTypingDelay", altscrname+".NoFocusWhileTypingDelay"),
workspaces(rm, 4, scrname+".workspaces", altscrname+".Workspaces"),
edge_snap_threshold(rm, 10, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"),
focused_alpha(rm, 255, scrname+".window.focus.alpha", altscrname+".Window.Focus.Alpha"),
unfocused_alpha(rm, 255, scrname+".window.unfocus.alpha", altscrname+".Window.Unfocus.Alpha"),
menu_alpha(rm, 255, scrname+".menu.alpha", altscrname+".Menu.Alpha"),
menu_delay(rm, 200, scrname + ".menuDelay", altscrname+".MenuDelay"),
tab_width(rm, 64, scrname + ".tab.width", altscrname+".Tab.Width"),
tooltip_delay(rm, 500, scrname + ".tooltipDelay", altscrname+".TooltipDelay"),
allow_remote_actions(rm, false, scrname+".allowRemoteActions", altscrname+".AllowRemoteActions"),
clientmenu_use_pixmap(rm, true, scrname+".clientMenu.usePixmap", altscrname+".ClientMenu.UsePixmap"),
tabs_use_pixmap(rm, true, scrname+".tabs.usePixmap", altscrname+".Tabs.UsePixmap"),
max_over_tabs(rm, false, scrname+".tabs.maxOver", altscrname+".Tabs.MaxOver"),
default_internal_tabs(rm, true /* TODO: autoconf option? */ , scrname+".tabs.intitlebar", altscrname+".Tabs.InTitlebar") {
}
BScreen::BScreen(FbTk::ResourceManager &rm,
const string &screenname,
@ -514,6 +409,7 @@ BScreen::~BScreen() {
FbTk::EventManager *evm = FbTk::EventManager::instance();
evm->remove(rootWindow());
Keys *keys = Fluxbox::instance()->keys();
if (keys)
keys->unregisterWindow(rootWindow().window());
@ -579,7 +475,6 @@ BScreen::~BScreen() {
// slit must be destroyed before headAreas (Struts)
m_slit.reset(0);
delete m_rootmenu.release();
delete m_workspacemenu.release();
delete m_windowmenu.release();
@ -590,7 +485,6 @@ BScreen::~BScreen() {
delete m_focus_control;
delete m_placement_strategy;
}
bool BScreen::isRestart() {
@ -1541,258 +1435,15 @@ float BScreen::getYGap(int head) {
}
void BScreen::setupConfigmenu(FbTk::Menu &menu) {
_FB_USES_NLS;
struct ConfigMenu::SetupHelper sh = {
.screen = *this,
.rm = m_resource_manager,
.resource = resource,
};
menu.removeAll();
FbTk::MacroCommand *s_a_reconf_macro = new FbTk::MacroCommand();
FbTk::MacroCommand *s_a_reconftabs_macro = new FbTk::MacroCommand();
FbTk::RefCount<FbTk::Command<void> > saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(
*Fluxbox::instance(),
&Fluxbox::save_rc));
FbTk::RefCount<FbTk::Command<void> > reconf_cmd(FbTk::CommandParser<void>::instance().parse("reconfigure"));
FbTk::RefCount<FbTk::Command<void> > reconftabs_cmd(new FbTk::SimpleCommand<BScreen>(
*this,
&BScreen::reconfigureTabs));
s_a_reconf_macro->add(saverc_cmd);
s_a_reconf_macro->add(reconf_cmd);
s_a_reconftabs_macro->add(saverc_cmd);
s_a_reconftabs_macro->add(reconftabs_cmd);
FbTk::RefCount<FbTk::Command<void> > save_and_reconfigure(s_a_reconf_macro);
FbTk::RefCount<FbTk::Command<void> > save_and_reconftabs(s_a_reconftabs_macro);
// create focus menu
// we don't set this to internal menu so will
// be deleted toghether with the parent
FbTk::FbString focusmenu_label = _FB_XTEXT(Configmenu, FocusModel,
"Focus Model",
"Method used to give focus to windows");
FbTk::Menu *focus_menu = createMenu(focusmenu_label);
#define _BOOLITEM(m,a, b, c, d, e, f) (m).insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(a, b, c, d), e, f))
#define _FOCUSITEM(a, b, c, d, e) \
focus_menu->insertItem(new FocusModelMenuItem(_FB_XTEXT(a, b, c, d), focusControl(), \
e, save_and_reconfigure))
_FOCUSITEM(Configmenu, ClickFocus,
"Click To Focus", "Click to focus",
FocusControl::CLICKFOCUS);
_FOCUSITEM(Configmenu, MouseFocus,
"Mouse Focus (Keyboard Friendly)",
"Mouse Focus (Keyboard Friendly)",
FocusControl::MOUSEFOCUS);
_FOCUSITEM(Configmenu, StrictMouseFocus,
"Mouse Focus (Strict)",
"Mouse Focus (Strict)",
FocusControl::STRICTMOUSEFOCUS);
#undef _FOCUSITEM
focus_menu->insertItem(new FbTk::MenuSeparator());
focus_menu->insertItem(new TabFocusModelMenuItem(_FB_XTEXT(Configmenu,
ClickTabFocus, "ClickTabFocus", "Click tab to focus windows"),
focusControl(), FocusControl::CLICKTABFOCUS, save_and_reconfigure));
focus_menu->insertItem(new TabFocusModelMenuItem(_FB_XTEXT(Configmenu,
MouseTabFocus, "MouseTabFocus", "Hover over tab to focus windows"),
focusControl(), FocusControl::MOUSETABFOCUS, save_and_reconfigure));
focus_menu->insertItem(new FbTk::MenuSeparator());
try {
focus_menu->insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(Configmenu, FocusNew,
"Focus New Windows", "Focus newly created windows"),
m_resource_manager.getResource<bool>(name() + ".focusNewWindows"),
saverc_cmd));
} catch (FbTk::ResourceException & e) {
cerr<<e.what()<<endl;
}
#ifdef XINERAMA
try {
focus_menu->insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(Configmenu, FocusSameHead,
"Keep Head", "Only revert focus on same head"),
m_resource_manager.getResource<bool>(name() + ".focusSameHead"),
saverc_cmd));
} catch (FbTk::ResourceException e) {
cerr<<e.what()<<endl;
}
#endif // XINERAMA
_BOOLITEM(*focus_menu, Configmenu, AutoRaise,
"Auto Raise", "Auto Raise windows on sloppy",
resource.auto_raise, saverc_cmd);
_BOOLITEM(*focus_menu, Configmenu, ClickRaises,
"Click Raises", "Click Raises",
resource.click_raises, saverc_cmd);
focus_menu->updateMenu();
menu.insertSubmenu(focusmenu_label, focus_menu);
// END focus menu
// BEGIN maximize menu
FbTk::FbString maxmenu_label = _FB_XTEXT(Configmenu, MaxMenu,
"Maximize Options", "heading for maximization options");
FbTk::Menu *maxmenu = createMenu(maxmenu_label);
_BOOLITEM(*maxmenu, Configmenu, FullMax,
"Full Maximization", "Maximise over slit, toolbar, etc",
resource.full_max, saverc_cmd);
_BOOLITEM(*maxmenu, Configmenu, MaxIgnoreInc,
"Ignore Resize Increment",
"Maximizing Ignores Resize Increment (e.g. xterm)",
resource.max_ignore_inc, saverc_cmd);
_BOOLITEM(*maxmenu, Configmenu, MaxDisableMove,
"Disable Moving", "Don't Allow Moving While Maximized",
resource.max_disable_move, saverc_cmd);
_BOOLITEM(*maxmenu, Configmenu, MaxDisableResize,
"Disable Resizing", "Don't Allow Resizing While Maximized",
resource.max_disable_resize, saverc_cmd);
maxmenu->updateMenu();
menu.insertSubmenu(maxmenu_label, maxmenu);
// END maximize menu
// BEGIN tab menu
FbTk::FbString tabmenu_label = _FB_XTEXT(Configmenu, TabMenu,
"Tab Options",
"heading for tab-related options");
FbTk::Menu *tab_menu = createMenu(tabmenu_label);
FbTk::FbString tabplacement_label = _FB_XTEXT(Menu, Placement, "Placement", "Title of Placement menu");
FbTk::Menu *tabplacement_menu = createToggleMenu(tabplacement_label);
tab_menu->insertSubmenu(tabplacement_label, tabplacement_menu);
_BOOLITEM(*tab_menu,Configmenu, TabsInTitlebar,
"Tabs in Titlebar", "Tabs in Titlebar",
resource.default_internal_tabs, save_and_reconftabs);
tab_menu->insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(Common, MaximizeOver,
"Maximize Over", "Maximize over this thing when maximizing"),
resource.max_over_tabs, save_and_reconfigure));
tab_menu->insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(Toolbar, ShowIcons,
"Show Pictures", "chooses if little icons are shown next to title in the iconbar"),
resource.tabs_use_pixmap, save_and_reconfigure));
FbTk::MenuItem *tab_width_item =
new FbTk::IntMenuItem(_FB_XTEXT(Configmenu, ExternalTabWidth,
"External Tab Width",
"Width of external-style tabs"),
resource.tab_width, 10, 3000, /* silly number */
*tab_menu);
tab_width_item->setCommand(save_and_reconftabs);
tab_menu->insertItem(tab_width_item);
// menu is 3 wide, 5 down
struct PlacementP {
const FbTk::FbString label;
FbWinFrame::TabPlacement placement;
};
static const PlacementP place_menu[] = {
{ _FB_XTEXT(Align, TopLeft, "Top Left", "Top Left"), FbWinFrame::TOPLEFT},
{ _FB_XTEXT(Align, LeftTop, "Left Top", "Left Top"), FbWinFrame::LEFTTOP},
{ _FB_XTEXT(Align, LeftCenter, "Left Center", "Left Center"), FbWinFrame::LEFT},
{ _FB_XTEXT(Align, LeftBottom, "Left Bottom", "Left Bottom"), FbWinFrame::LEFTBOTTOM},
{ _FB_XTEXT(Align, BottomLeft, "Bottom Left", "Bottom Left"), FbWinFrame::BOTTOMLEFT},
{ _FB_XTEXT(Align, TopCenter, "Top Center", "Top Center"), FbWinFrame::TOP},
{ "", FbWinFrame::TOPLEFT},
{ "", FbWinFrame::TOPLEFT},
{ "", FbWinFrame::TOPLEFT},
{ _FB_XTEXT(Align, BottomCenter, "Bottom Center", "Bottom Center"), FbWinFrame::BOTTOM},
{ _FB_XTEXT(Align, TopRight, "Top Right", "Top Right"), FbWinFrame::TOPRIGHT},
{ _FB_XTEXT(Align, RightTop, "Right Top", "Right Top"), FbWinFrame::RIGHTTOP},
{ _FB_XTEXT(Align, RightCenter, "Right Center", "Right Center"), FbWinFrame::RIGHT},
{ _FB_XTEXT(Align, RightBottom, "Right Bottom", "Right Bottom"), FbWinFrame::RIGHTBOTTOM},
{ _FB_XTEXT(Align, BottomRight, "Bottom Right", "Bottom Right"), FbWinFrame::BOTTOMRIGHT}
};
tabplacement_menu->setMinimumColumns(3);
// create items in sub menu
for (size_t i=0; i< sizeof(place_menu)/sizeof(PlacementP); ++i) {
const PlacementP& p = place_menu[i];
if (p.label == "") {
tabplacement_menu->insert(p.label);
tabplacement_menu->setItemEnabled(i, false);
} else
tabplacement_menu->insertItem(new TabPlacementMenuItem(p.label, *this, p.placement, save_and_reconftabs));
}
tabplacement_menu->updateMenu();
menu.insertSubmenu(tabmenu_label, tab_menu);
#ifdef HAVE_XRENDER
if (FbTk::Transparent::haveRender() ||
FbTk::Transparent::haveComposite()) {
FbTk::FbString alphamenu_label = _FB_XTEXT(Configmenu, Transparency,
"Transparency",
"Menu containing various transparency options");
FbTk::Menu *alpha_menu = createMenu(alphamenu_label);
if (FbTk::Transparent::haveComposite(true)) {
static FbTk::SimpleAccessor<bool> s_pseudo(Fluxbox::instance()->getPseudoTrans());
alpha_menu->insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(Configmenu, ForcePseudoTrans,
"Force Pseudo-Transparency",
"When composite is available, still use old pseudo-transparency"),
s_pseudo, save_and_reconfigure));
}
// in order to save system resources, don't save or reconfigure alpha
// settings until after the user is done changing them
FbTk::RefCount<FbTk::Command<void> > delayed_save_and_reconf(
new FbTk::DelayedCmd(save_and_reconfigure));
FbTk::MenuItem *focused_alpha_item =
new FbTk::IntMenuItem(_FB_XTEXT(Configmenu, FocusedAlpha,
"Focused Window Alpha",
"Transparency level of the focused window"),
resource.focused_alpha, 0, 255, *alpha_menu);
focused_alpha_item->setCommand(delayed_save_and_reconf);
alpha_menu->insertItem(focused_alpha_item);
FbTk::MenuItem *unfocused_alpha_item =
new FbTk::IntMenuItem(_FB_XTEXT(Configmenu,
UnfocusedAlpha,
"Unfocused Window Alpha",
"Transparency level of unfocused windows"),
resource.unfocused_alpha, 0, 255, *alpha_menu);
unfocused_alpha_item->setCommand(delayed_save_and_reconf);
alpha_menu->insertItem(unfocused_alpha_item);
FbTk::MenuItem *menu_alpha_item =
new FbTk::IntMenuItem(_FB_XTEXT(Configmenu, MenuAlpha,
"Menu Alpha", "Transparency level of menu"),
resource.menu_alpha, 0, 255, *alpha_menu);
menu_alpha_item->setCommand(delayed_save_and_reconf);
alpha_menu->insertItem(menu_alpha_item);
alpha_menu->updateMenu();
menu.insertSubmenu(alphamenu_label, alpha_menu);
}
#endif // HAVE_XRENDER
Configmenus::iterator it = m_configmenu_list.begin();
Configmenus::iterator it_end = m_configmenu_list.end();
for (; it != it_end; ++it)
menu.insertSubmenu(it->first, it->second);
_BOOLITEM(menu, Configmenu, OpaqueMove,
"Opaque Window Moving",
"Window Moving with whole window visible (as opposed to outline moving)",
resource.opaque_move, saverc_cmd);
_BOOLITEM(menu, Configmenu, WorkspaceWarping,
"Workspace Warping",
"Workspace Warping - dragging windows to the edge and onto the next workspace",
resource.workspace_warping, saverc_cmd);
#undef _BOOLITEM
// finaly update menu
ConfigMenu::setup(menu, sh);
menu.updateMenu();
}

View file

@ -31,6 +31,7 @@
#include "WinButtonTheme.hh"
#include "FbWinFrameTheme.hh"
#include "TooltipWindow.hh"
#include "ScreenResource.hh"
#include "FbTk/MenuTheme.hh"
#include "FbTk/EventHandler.hh"
@ -522,32 +523,12 @@ private:
std::auto_ptr<RootTheme> m_root_theme;
FbRootWindow m_root_window;
std::auto_ptr<OSDWindow> m_geom_window, m_pos_window;
std::auto_ptr<OSDWindow> m_geom_window;
std::auto_ptr<OSDWindow> m_pos_window;
std::auto_ptr<TooltipWindow> m_tooltip_window;
FbTk::FbWindow m_dummy_window;
struct ScreenResource {
ScreenResource(FbTk::ResourceManager &rm, const std::string &scrname,
const std::string &altscrname);
FbTk::Resource<bool> opaque_move, full_max,
max_ignore_inc, max_disable_move, max_disable_resize,
workspace_warping, show_window_pos, auto_raise, click_raises;
FbTk::Resource<std::string> default_deco;
FbTk::Resource<FbWinFrame::TabPlacement> tab_placement;
FbTk::Resource<std::string> windowmenufile;
FbTk::Resource<unsigned int> typing_delay;
FbTk::Resource<int> workspaces, edge_snap_threshold, focused_alpha,
unfocused_alpha, menu_alpha, menu_delay,
tab_width, tooltip_delay;
FbTk::Resource<bool> allow_remote_actions;
FbTk::Resource<bool> clientmenu_use_pixmap;
FbTk::Resource<bool> tabs_use_pixmap;
FbTk::Resource<bool> max_over_tabs;
FbTk::Resource<bool> default_internal_tabs;
} resource;
ScreenResource resource;
/// Holds manage resources that screen destroys
FbTk::ResourceManager::ResourceList m_managed_resources;

112
src/ScreenResource.cc Normal file
View file

@ -0,0 +1,112 @@
// ScreenResource.cc for Fluxbox Window Manager
// Copyright (c) 2015 - Mathias Gumz <akira@fluxbox.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include "ScreenResource.hh"
#include "fluxbox.hh"
#include "FbTk/Util.hh"
#include <cstring>
namespace {
struct TabPlacementString {
FbWinFrame::TabPlacement placement;
const char* str;
};
const TabPlacementString _PLACEMENT_STRINGS[] = {
{ FbWinFrame::TOPLEFT, "TopLeft" },
{ FbWinFrame::TOP, "Top" },
{ FbWinFrame::TOPRIGHT, "TopRight" },
{ FbWinFrame::BOTTOMLEFT, "BottomLeft" },
{ FbWinFrame::BOTTOM, "Bottom" },
{ FbWinFrame::BOTTOMRIGHT, "BottomRight" },
{ FbWinFrame::LEFTBOTTOM, "LeftBottom" },
{ FbWinFrame::LEFT, "Left" },
{ FbWinFrame::LEFTTOP, "LeftTop" },
{ FbWinFrame::RIGHTBOTTOM, "RightBottom" },
{ FbWinFrame::RIGHT, "Right" },
{ FbWinFrame::RIGHTTOP, "RightTop" }
};
}
namespace FbTk {
template<>
std::string FbTk::Resource<FbWinFrame::TabPlacement>::
getString() const {
size_t i = (m_value == FbTk::Util::clamp(m_value, FbWinFrame::TOPLEFT, FbWinFrame::RIGHTTOP)
? m_value
: FbWinFrame::DEFAULT) - 1;
return _PLACEMENT_STRINGS[i].str;
}
template<>
void FbTk::Resource<FbWinFrame::TabPlacement>::
setFromString(const char *strval) {
size_t i;
for (i = 0; i < sizeof(_PLACEMENT_STRINGS)/sizeof(_PLACEMENT_STRINGS[0]); ++i) {
if (strcasecmp(strval, _PLACEMENT_STRINGS[i].str) == 0) {
m_value = _PLACEMENT_STRINGS[i].placement;
return;
}
}
setDefaultValue();
}
} // end namespace FbTk
ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
const std::string &scrname,
const std::string &altscrname):
opaque_move(rm, true, scrname + ".opaqueMove", altscrname+".OpaqueMove"),
full_max(rm, false, scrname+".fullMaximization", altscrname+".FullMaximization"),
max_ignore_inc(rm, true, scrname+".maxIgnoreIncrement", altscrname+".MaxIgnoreIncrement"),
max_disable_move(rm, false, scrname+".maxDisableMove", altscrname+".MaxDisableMove"),
max_disable_resize(rm, false, scrname+".maxDisableResize", altscrname+".MaxDisableResize"),
workspace_warping(rm, true, scrname+".workspacewarping", altscrname+".WorkspaceWarping"),
show_window_pos(rm, false, scrname+".showwindowposition", altscrname+".ShowWindowPosition"),
auto_raise(rm, true, scrname+".autoRaise", altscrname+".AutoRaise"),
click_raises(rm, true, scrname+".clickRaises", altscrname+".ClickRaises"),
default_deco(rm, "NORMAL", scrname+".defaultDeco", altscrname+".DefaultDeco"),
tab_placement(rm, FbWinFrame::TOPLEFT, scrname+".tab.placement", altscrname+".Tab.Placement"),
windowmenufile(rm, Fluxbox::instance()->getDefaultDataFilename("windowmenu"), scrname+".windowMenu", altscrname+".WindowMenu"),
typing_delay(rm, 0, scrname+".noFocusWhileTypingDelay", altscrname+".NoFocusWhileTypingDelay"),
workspaces(rm, 4, scrname+".workspaces", altscrname+".Workspaces"),
edge_snap_threshold(rm, 10, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"),
focused_alpha(rm, 255, scrname+".window.focus.alpha", altscrname+".Window.Focus.Alpha"),
unfocused_alpha(rm, 255, scrname+".window.unfocus.alpha", altscrname+".Window.Unfocus.Alpha"),
menu_alpha(rm, 255, scrname+".menu.alpha", altscrname+".Menu.Alpha"),
menu_delay(rm, 200, scrname + ".menuDelay", altscrname+".MenuDelay"),
tab_width(rm, 64, scrname + ".tab.width", altscrname+".Tab.Width"),
tooltip_delay(rm, 500, scrname + ".tooltipDelay", altscrname+".TooltipDelay"),
allow_remote_actions(rm, false, scrname+".allowRemoteActions", altscrname+".AllowRemoteActions"),
clientmenu_use_pixmap(rm, true, scrname+".clientMenu.usePixmap", altscrname+".ClientMenu.UsePixmap"),
tabs_use_pixmap(rm, true, scrname+".tabs.usePixmap", altscrname+".Tabs.UsePixmap"),
max_over_tabs(rm, false, scrname+".tabs.maxOver", altscrname+".Tabs.MaxOver"),
default_internal_tabs(rm, true /* TODO: autoconf option? */ , scrname+".tabs.intitlebar", altscrname+".Tabs.InTitlebar") {
}

63
src/ScreenResource.hh Normal file
View file

@ -0,0 +1,63 @@
#ifndef SCREEN_RESOURCE_HH
#define SCREEN_RESOURCE_HH
// ScreenResource.hh for Fluxbox Window Manager
// Copyright (c) 2015 - Mathias Gumz <akira@fluxbox.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include "FbWinFrame.hh"
#include "FbTk/Resource.hh"
#include <string>
struct ScreenResource {
ScreenResource(FbTk::ResourceManager &rm,
const std::string &scrname, const std::string &altscrname);
FbTk::Resource<bool> opaque_move,
full_max,
max_ignore_inc,
max_disable_move,
max_disable_resize,
workspace_warping,
show_window_pos,
auto_raise,
click_raises;
FbTk::Resource<std::string> default_deco;
FbTk::Resource<FbWinFrame::TabPlacement> tab_placement;
FbTk::Resource<std::string> windowmenufile;
FbTk::Resource<unsigned int> typing_delay;
FbTk::Resource<int> workspaces,
edge_snap_threshold,
focused_alpha,
unfocused_alpha,
menu_alpha,
menu_delay,
tab_width,
tooltip_delay;
FbTk::Resource<bool> allow_remote_actions;
FbTk::Resource<bool> clientmenu_use_pixmap;
FbTk::Resource<bool> tabs_use_pixmap;
FbTk::Resource<bool> max_over_tabs;
FbTk::Resource<bool> default_internal_tabs;
};
#endif