external tabs features and bugfixes

This commit is contained in:
simonb 2006-03-22 12:23:17 +00:00
parent da365bb4c9
commit fe4a7db228
9 changed files with 418 additions and 73 deletions

View file

@ -1,5 +1,14 @@
(Format: Year/Month/Day)
Changes for 0.9.16:
*06/03/22:
* More external tabs work (Simon)
- Can now be placed TopLeft/TopRight/BottomLeft/BottomRight
- New "Tab Options" config menu, with (efficient) runtime updating
- edge snapping includes tabs
- decoration fixes where some missed the tab option
- label text color was not updated
Screen.hh/cc Window.hh/cc FbWinFrame.hh/cc Container.cc
fluxbox-nls.hh
*06/03/20:
* Fix placement config (some compilers resulted in ignoring of
placement policy setting), and a minor ext. tabs placement bug

View file

@ -72,7 +72,8 @@ enum {
ConfigmenuTransparency = 18,
ConfigmenuFocusedAlpha = 19,
ConfigmenuUnfocusedAlpha = 20,
ConfigmenuExternalTabs = 21,
ConfigmenuTabMenu = 21,
ConfigmenuTabsInTitlebar = 22,
EwmhSet = 5,
EwmhOutOfMemoryClientList = 1,

View file

@ -264,10 +264,16 @@ void Container::setMaxSizePerClient(unsigned int size) {
}
void Container::setMaxTotalSize(unsigned int size) {
if (m_max_total_size == size)
return;
unsigned int old = m_max_total_size;
m_max_total_size = size;
if (m_max_total_size && width() > m_max_total_size) {
resize(m_max_total_size, height());
} else if (!m_max_total_size && old) { // going from restricted to unrestricted
repositionItems();
} else {
// this is a bit of duplication from repositionItems
// for when we are allowed to grow ourself
@ -286,7 +292,6 @@ void Container::setMaxTotalSize(unsigned int size) {
if (preferred_width != width())
repositionItems();
}
}
}
@ -381,7 +386,10 @@ void Container::repositionItems() {
}
if (total_width != width()) {
// calling Container::resize here risks infinite loops
FbTk::FbWindow::resize(total_width, height());
if (align == RIGHT)
FbTk::FbWindow::moveResize(x() - (total_width - width()), y(), total_width, height());
else
FbTk::FbWindow::resize(total_width, height());
}
}
@ -396,7 +404,7 @@ void Container::repositionItems() {
int direction = 1;
if (align == RIGHT) {
direction = -1;
next_x = total_width - max_width_per_client + borderW;
next_x = total_width - max_width_per_client - borderW;
}
for (; it != it_end; ++it, next_x += direction*(max_width_per_client + borderW + extra)) {

View file

@ -80,6 +80,7 @@ FbWinFrame::FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageContr
EnterWindowMask | LeaveWindowMask),
m_bevel(1),
m_use_titlebar(true),
m_tabplacement(BOTTOMRIGHT),
m_use_tabs(true),
m_use_handle(true),
m_focused(false),
@ -126,9 +127,11 @@ bool FbWinFrame::setTabMode(TabMode tabmode) {
if (tabmode == NOTSET)
tabmode = m_tabmode;
m_tabmode = tabmode;
// reparent tab container
if (tabmode == EXTERNAL) {
m_label.show();
m_tab_container.setBorderWidth(m_window.borderWidth());
m_tab_container.setBorderColor(theme().border().color());
m_tab_container.setEventMask(
@ -141,15 +144,35 @@ bool FbWinFrame::setTabMode(TabMode tabmode) {
GrabModeSync, GrabModeSync, None, None);
XUngrabButton(m_tab_container.display(), Button1, Mod1Mask|Mod2Mask|Mod3Mask, m_tab_container.window());
int tabx, taby;
switch (m_tabplacement) {
case TOPLEFT:
m_tab_container.setAlignment(Container::LEFT);
tabx = x();
taby = y() - yOffset();
break;
case TOPRIGHT:
m_tab_container.setAlignment(Container::RIGHT);
tabx = x() + width() - m_tab_container.width();
taby = y() - yOffset();
break;
case BOTTOMLEFT:
m_tab_container.setAlignment(Container::LEFT);
tabx = x();
taby = y() + height() + m_window.borderWidth();
break;
case BOTTOMRIGHT:
m_tab_container.setAlignment(Container::RIGHT);
tabx = x() + width() - m_tab_container.width();
taby = y() + height() + m_window.borderWidth();
break;
}
if (m_tab_container.parent()->window() != m_screen.rootWindow().window()) {
int tabx = x();
// one borderwidth only, so the adjacent borders overlab
int taby = y() - m_tab_container.height() - m_tab_container.borderWidth();
m_tab_container.reparent(m_screen.rootWindow(), tabx, taby);
m_layeritem.addWindow(m_tab_container);
}
m_tab_container.setAlignment(Container::LEFT);
m_tab_container.setMaxSizePerClient(64); //!!TODO make this a setting
m_tab_container.setMaxTotalSize(window().width());
@ -162,23 +185,24 @@ bool FbWinFrame::setTabMode(TabMode tabmode) {
}
} else {
m_tab_container.setAlignment(Container::RELATIVE);
if (m_tab_container.parent()->window() == m_screen.rootWindow().window()) {
m_layeritem.removeWindow(m_tab_container);
m_tab_container.reparent(m_titlebar, m_label.x(), m_label.y());
m_tab_container.resize(m_label.width(), m_label.height());
m_tab_container.raise();
}
m_tab_container.setBorderWidth(0);
m_tab_container.setMaxTotalSize(0);
m_tab_container.setMaxSizePerClient(0);
m_tab_container.setAlignment(Container::RELATIVE);
if (!m_use_tabs)
m_tab_container.show();
else
ret = false;
m_label.hide();
// reconfigure();
}
m_tabmode = tabmode;
return true;
}
@ -286,7 +310,7 @@ void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int heigh
m_window.resize(width, height);
}
if (move)
if (move || resize && m_tabplacement != TOPLEFT)
alignTabs();
if (resize) {
@ -306,8 +330,30 @@ void FbWinFrame::quietMoveResize(int x, int y,
}
void FbWinFrame::alignTabs() {
if (m_tabmode == EXTERNAL)
m_tab_container.move(m_window.x(), m_window.y() - m_tab_container.height() - m_tab_container.borderWidth());
if (m_tabmode != EXTERNAL)
return;
int tabx = 0, taby = 0;
switch (m_tabplacement) {
case TOPLEFT:
tabx = x();
taby = y() - yOffset();
break;
case TOPRIGHT:
tabx = x() + width() - m_tab_container.width();
taby = y() - yOffset();
break;
case BOTTOMLEFT:
tabx = x();
taby = y() + height() + m_window.borderWidth();
break;
case BOTTOMRIGHT:
tabx = x() + width() - m_tab_container.width();
taby = y() + height() + m_window.borderWidth();
break;
}
m_tab_container.move(tabx, taby);
}
void FbWinFrame::notifyMoved(bool clear) {
@ -1077,6 +1123,9 @@ void FbWinFrame::applyTitlebar() {
m_titlebar.setAlpha(alpha);
m_label.setAlpha(alpha);
if (externalTabMode())
m_label.setGC(m_focused?theme().labelTextFocusGC():theme().labelTextUnfocusGC());
if (label_pm != 0)
m_label.setBackgroundPixmap(label_pm);
else
@ -1398,6 +1447,7 @@ void FbWinFrame::applyFocusLabel(FbTk::TextButton &button) {
}
void FbWinFrame::applyActiveLabel(FbTk::TextButton &button) {
button.setBorderWidth(1);
button.setGC(theme().labelTextActiveGC());
button.setJustify(theme().justify());
@ -1544,16 +1594,26 @@ void FbWinFrame::gravityTranslate(int &x, int &y, unsigned int width, unsigned i
}
int FbWinFrame::heightOffset() const {
if (m_tabmode == EXTERNAL && m_use_tabs)
return m_tab_container.height() + m_window.borderWidth();
else
if (m_tabmode != EXTERNAL || !m_use_tabs)
return 0;
// same height offset for top and bottom tabs
return m_tab_container.height() + m_window.borderWidth();
}
int FbWinFrame::yOffset() const {
if (m_tabmode == EXTERNAL && m_use_tabs)
return m_tab_container.height() + m_window.borderWidth();
else
if (m_tabmode != EXTERNAL || !m_use_tabs)
return 0;
switch (m_tabplacement) {
case TOPLEFT:
case TOPRIGHT:
return m_tab_container.height() + m_window.borderWidth();
break;
case BOTTOMLEFT:
case BOTTOMRIGHT:
return 0;
break;
}
}

View file

@ -59,6 +59,17 @@ public:
// STRICTINTERNAL means it doesn't go external automatically when no titlebar
enum TabMode { NOTSET = 0, INTERNAL = 1, EXTERNAL };
/// Toolbar placement on the screen
enum TabPlacement{
// top and bottom placement
TOPLEFT = 1, BOTTOMLEFT,
TOPRIGHT, BOTTOMRIGHT
// left and right placement
// LEFTBOTTOM, LEFTTOP,
// RIGHTBOTTOM, RIGHTTOP
};
typedef FbTk::TextButton *ButtonId; ///< defines a button id
/// create a top level window
@ -114,6 +125,7 @@ public:
inline void setFocusTitle(const std::string &str) { m_label.setText(str); }
void setDoubleClickTime(unsigned int time);
bool setTabMode(TabMode tabmode);
inline void setTabPlacement(TabPlacement tabplacement) { m_tabplacement = tabplacement; alignTabs(); }
/// add a button to the left of the label
void addLeftButton(FbTk::Button *btn);
@ -222,7 +234,7 @@ public:
unsigned int titlebarHeight() const { return m_titlebar.height(); }
/// @return size of button
unsigned int buttonHeight() const;
bool externalTabMode() const { return m_tabmode == EXTERNAL; }
bool externalTabMode() const { return m_tabmode == EXTERNAL && m_use_tabs; }
inline const FbTk::XLayerItem &layerItem() const { return m_layeritem; }
inline FbTk::XLayerItem &layerItem() { return m_layeritem; }
@ -355,6 +367,7 @@ private:
//@}
TabMode m_tabmode;
TabPlacement m_tabplacement;
bool m_need_render;
int m_button_size; ///< size for all titlebar buttons

View file

@ -156,9 +156,93 @@ int anotherWMRunning(Display *display, XErrorEvent *) {
}
class TabPlacementMenuItem: public FbTk::MenuItem {
public:
TabPlacementMenuItem(const char * label, BScreen &screen, FbWinFrame::TabPlacement place, FbTk::RefCount<FbTk::Command> &cmd):
FbTk::MenuItem(label, cmd),
m_screen(screen),
m_place(place) { }
bool isEnabled() const { return m_screen.getTabPlacement() != m_place; }
void click(int button, int time) {
m_screen.saveTabPlacement(m_place);
FbTk::MenuItem::click(button, time);
}
private:
BScreen &m_screen;
FbWinFrame::TabPlacement m_place;
};
} // end anonymous namespace
namespace FbTk {
template<>
void FbTk::Resource<FbWinFrame::TabPlacement>::
setFromString(const char *strval) {
if (strcasecmp(strval, "TopLeft")==0)
m_value = FbWinFrame::TOPLEFT;
else if (strcasecmp(strval, "BottomLeft")==0)
m_value = FbWinFrame::BOTTOMLEFT;
else if (strcasecmp(strval, "TopRight")==0)
m_value = FbWinFrame::TOPRIGHT;
else if (strcasecmp(strval, "BottomRight")==0)
m_value = FbWinFrame::BOTTOMRIGHT;
/*
else if (strcasecmp(strval, "LeftTop") == 0)
m_value = FbWinFrame::LEFTTOP;
else if (strcasecmp(strval, "LeftBottom") == 0)
m_value = FbWinFrame::LEFTBOTTOM;
else if (strcasecmp(strval, "RightTop") == 0)
m_value = FbWinFrame::RIGHTTOP;
else if (strcasecmp(strval, "RightBottom") == 0)
m_value = FbWinFrame::RIGHTBOTTOM;
*/
else
setDefaultValue();
}
template<>
string FbTk::Resource<FbWinFrame::TabPlacement>::
getString() const {
switch (m_value) {
case FbWinFrame::TOPLEFT:
return string("TopLeft");
break;
case FbWinFrame::BOTTOMLEFT:
return string("BottomLeft");
break;
case FbWinFrame::TOPRIGHT:
return string("TopRight");
break;
case FbWinFrame::BOTTOMRIGHT:
return string("BottomRight");
break;
/*
case FbWinFrame::LEFTTOP:
return string("LeftTop");
break;
case FbWinFrame::LEFTBOTTOM:
return string("LeftBottom");
break;
case FbWinFrame::RIGHTTOP:
return string("RightTop");
break;
case FbWinFrame::RIGHTBOTTOM:
return string("RightBottom");
break;
*/
}
//default string
return string("TopLeft");
}
} // end namespace FbTk
BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
const std::string &scrname,
const std::string &altscrname):
@ -176,6 +260,7 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
decorate_transient(rm, false, scrname+".decorateTransient", altscrname+".DecorateTransient"),
rootcommand(rm, "", scrname+".rootCommand", altscrname+".RootCommand"),
resize_model(rm, BOTTOMRESIZE, scrname+".resizeMode", altscrname+".ResizeMode"),
tab_placement(rm, FbWinFrame::TOPLEFT, scrname+".tab.placement", altscrname+".Tab.Placement"),
windowmenufile(rm, "", scrname+".windowMenu", altscrname+".WindowMenu"),
follow_model(rm, IGNORE_OTHER_WORKSPACES, scrname+".followModel", altscrname+".followModel"),
workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"),
@ -202,7 +287,7 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
altscrname+".overlay.CapStyle"),
scroll_action(rm, "", scrname+".windowScrollAction", altscrname+".WindowScrollAction"),
scroll_reverse(rm, false, scrname+".windowScrollReverse", altscrname+".WindowScrollReverse"),
default_external_tabs(rm, false /* TODO: autoconf option? */ , scrname+".externalTabs", altscrname+".ExternalTabs") {
default_internal_tabs(rm, false /* TODO: autoconf option? */ , scrname+".tabs.intitlebar", altscrname+".Tabs.InTitlebar") {
}
@ -330,7 +415,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
}
m_current_workspace = m_workspaces_list.front();
//!! TODO: we shouldn't do this more than once, but since slit handles their
// own resources we must do this.
@ -626,6 +711,15 @@ FbTk::Menu *BScreen::createMenu(const std::string &label) {
return menu;
}
FbTk::Menu *BScreen::createToggleMenu(const std::string &label) {
FbTk::Menu *menu = new ToggleMenu(menuTheme(),
imageControl(),
*layerManager().getLayer(Layer::MENU));
if (!label.empty())
menu->setLabel(label.c_str());
return menu;
}
void BScreen::addExtraWindowMenu(const char *label, FbTk::Menu *menu) {
menu->setInternalMenu();
@ -794,6 +888,26 @@ void BScreen::reconfigure() {
FbTk::ThemeManager::instance().load(fluxbox->getStyleFilename(),
fluxbox->getStyleOverlayFilename(),
m_root_theme->screenNum());
reconfigureTabs();
}
void BScreen::reconfigureTabs() {
Workspaces::iterator w_it = getWorkspacesList().begin();
const Workspaces::iterator w_it_end = getWorkspacesList().end();
for (; w_it != w_it_end; ++w_it) {
if ((*w_it)->windowList().size()) {
Workspace::Windows::iterator win_it = (*w_it)->windowList().begin();
const Workspace::Windows::iterator win_it_end = (*w_it)->windowList().end();
for (; win_it != win_it_end; ++win_it) {
(*win_it)->frame().setTabPlacement(*resource.tab_placement);
if (*resource.default_internal_tabs)
(*win_it)->frame().setTabMode(FbWinFrame::INTERNAL);
else
(*win_it)->frame().setTabMode(FbWinFrame::EXTERNAL);
}
}
}
}
@ -1454,12 +1568,21 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
menu.removeAll();
FbTk::MacroCommand *s_a_reconf_macro = new FbTk::MacroCommand();
FbTk::RefCount<FbTk::Command> saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(*Fluxbox::instance(),
&Fluxbox::save_rc));
FbTk::MacroCommand *s_a_reconftabs_macro = new FbTk::MacroCommand();
FbTk::RefCount<FbTk::Command> saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(
*Fluxbox::instance(),
&Fluxbox::save_rc));
FbTk::RefCount<FbTk::Command> reconf_cmd(CommandParser::instance().parseLine("reconfigure"));
FbTk::RefCount<FbTk::Command> 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> save_and_reconfigure(s_a_reconf_macro);
FbTk::RefCount<FbTk::Command> 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
@ -1468,6 +1591,9 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
"Method used to give focus to windows");
FbTk::Menu *focus_menu = createMenu(focusmenu_label ? focusmenu_label : "");
#define _BOOLITEM(m,a, b, c, d, e, f) (m).insert(new BoolMenuItem(_FBTEXT(a, b, c, d), e, f))
#define _FOCUSITEM(a, b, c, d, e) \
focus_menu->insert(new FocusModelMenuItem(_FBTEXT(a, b, c, d), focusControl(), \
e, save_and_reconfigure))
@ -1498,6 +1624,84 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
focus_menu->updateMenu();
menu.insert(focusmenu_label, focus_menu);
// END focus menu
// BEGIN tab menu
const char *tabmenu_label = _FBTEXT(Configmenu, TabMenu,
"Tab Options",
"heading for tab-related options");
FbTk::Menu *tab_menu = createMenu(tabmenu_label ? tabmenu_label : "");
const char *tabplacement_label = _FBTEXT(Menu, Placement, "Placement", "Title of Placement menu");
FbTk::Menu *tabplacement_menu = createToggleMenu(tabplacement_label);
tab_menu->insert(tabplacement_label, tabplacement_menu);
_BOOLITEM(*tab_menu,Configmenu, TabsInTitlebar,
"Tabs in Titlebar", "Tabs in Titlebar",
*resource.default_internal_tabs, save_and_reconftabs);
typedef pair<const char*, FbWinFrame::TabPlacement> PlacementP;
typedef list<PlacementP> Placements;
Placements place_menu;
// menu is 3 wide, 5 down
place_menu.push_back(PlacementP(_FBTEXT(Align, TopLeft, "Top Left", "Top Left"), FbWinFrame::TOPLEFT));
place_menu.push_back(PlacementP(_FBTEXT(Align, BottomLeft, "Bottom Left", "Bottom Left"), FbWinFrame::BOTTOMLEFT));
place_menu.push_back(PlacementP(_FBTEXT(Align, TopRight, "Top Right", "Top Right"), FbWinFrame::TOPRIGHT));
place_menu.push_back(PlacementP(_FBTEXT(Align, BottomRight, "Bottom Right", "Bottom Right"), FbWinFrame::BOTTOMRIGHT));
/*
place_menu.push_back(PlacementP(_FBTEXT(Align, LeftTop, "Left Top", "Left Top"), FbWinFrame::LEFTTOP));
place_menu.push_back(PlacementP(_FBTEXT(Align, LeftBottom, "Left Bottom", "Left Bottom"), FbWinFrame::LEFTBOTTOM));
place_menu.push_back(PlacementP(_FBTEXT(Align, RightTop, "Right Top", "Right Top"), FbWinFrame::RIGHTTOP));
place_menu.push_back(PlacementP(_FBTEXT(Align, RightBottom, "Right Bottom", "Right Bottom"), FbWinFrame::RIGHTBOTTOM));
*/
tabplacement_menu->setMinimumSublevels(2);
// create items in sub menu
size_t i=0;
while (!place_menu.empty()) {
i++;
const char *str = place_menu.front().first;
FbWinFrame::TabPlacement placement = place_menu.front().second;
if (str == 0) {
tabplacement_menu->insert("");
tabplacement_menu->setItemEnabled(i, false);
} else {
tabplacement_menu->insert(new TabPlacementMenuItem(str, *this, placement, save_and_reconftabs));
}
place_menu.pop_front();
}
tabplacement_menu->updateMenu();
menu.insert(tabmenu_label, tab_menu);
#undef _FOCUSITEM
focus_menu->insert(new TabFocusModelMenuItem("ClickTabFocus", focusControl(),
FocusControl::CLICKTABFOCUS,
save_and_reconfigure));
focus_menu->insert(new TabFocusModelMenuItem("MouseTabFocus", focusControl(),
FocusControl::MOUSETABFOCUS,
save_and_reconfigure));
focus_menu->insert(new BoolMenuItem(_FBTEXT(Configmenu,
AutoRaise,
"Auto Raise",
"Auto Raise windows on sloppy"),
*resource.auto_raise,
save_and_reconfigure));
focus_menu->updateMenu();
menu.insert(focusmenu_label, focus_menu);
// end tab menu
#ifdef SLIT
if (slit() != 0) {
slit()->menu().setInternalMenu();
@ -1510,20 +1714,18 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
for (; it != it_end; ++it)
menu.insert(it->first, it->second);
#define _BOOLITEM(a, b, c, d, e, f) menu.insert(new BoolMenuItem(_FBTEXT(a, b, c, d), e, f))
_BOOLITEM(Configmenu, ImageDithering,
_BOOLITEM(menu, Configmenu, ImageDithering,
"Image Dithering", "Image Dithering",
*resource.image_dither, save_and_reconfigure);
_BOOLITEM(Configmenu, OpaqueMove,
_BOOLITEM(menu, Configmenu, OpaqueMove,
"Opaque Window Moving",
"Window Moving with whole window visible (as opposed to outline moving)",
*resource.opaque_move, saverc_cmd);
_BOOLITEM(Configmenu, FullMax,
_BOOLITEM(menu, Configmenu, FullMax,
"Full Maximization", "Maximise over slit, toolbar, etc",
*resource.full_max, saverc_cmd);
try {
_BOOLITEM(Configmenu, FocusNew,
_BOOLITEM(menu, Configmenu, FocusNew,
"Focus New Windows", "Focus newly created windows",
*m_resource_manager.getResource<bool>(name() + ".focusNewWindows"),
saverc_cmd);
@ -1532,7 +1734,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
}
try {
_BOOLITEM(Configmenu, FocusLast,
_BOOLITEM(menu, Configmenu, FocusLast,
"Focus Last Window on Workspace", "Focus Last Window on Workspace",
*resourceManager().getResource<bool>(name() + ".focusLastWindow"),
saverc_cmd);
@ -1540,20 +1742,17 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
cerr<<e.what()<<endl;
}
_BOOLITEM(Configmenu, WorkspaceWarping,
_BOOLITEM(menu, Configmenu, WorkspaceWarping,
"Workspace Warping",
"Workspace Warping - dragging windows to the edge and onto the next workspace",
*resource.workspace_warping, saverc_cmd);
_BOOLITEM(Configmenu, DesktopWheeling,
_BOOLITEM(menu, Configmenu, DesktopWheeling,
"Desktop MouseWheel Switching", "Workspace switching using mouse wheel",
*resource.desktop_wheeling, saverc_cmd);
_BOOLITEM(Configmenu, DecorateTransient,
_BOOLITEM(menu, Configmenu, DecorateTransient,
"Decorate Transient Windows", "Decorate Transient Windows",
*resource.decorate_transient, saverc_cmd);
_BOOLITEM(Configmenu, ExternalTabs,
"Use External Tabs (experimental)", "Use External Tabs (experimental)",
*resource.default_external_tabs, saverc_cmd);
_BOOLITEM(Configmenu, ClickRaises,
_BOOLITEM(menu, Configmenu, ClickRaises,
"Click Raises", "Click Raises",
*resource.click_raises, saverc_cmd);

View file

@ -27,7 +27,7 @@
#ifndef SCREEN_HH
#define SCREEN_HH
#include "FbWinFrame.hh"
#include "FbRootWindow.hh"
#include "MenuTheme.hh"
#include "PlacementStrategy.hh"
@ -132,13 +132,15 @@ public:
ExtraMenus &extraWindowMenus() { return m_extramenus; }
const ExtraMenus &extraWindowMenus() const { return m_extramenus; }
FbWinFrame::TabPlacement getTabPlacement() const { return *resource.tab_placement; }
ResizeModel getResizeModel() const { return *resource.resize_model; }
inline FollowModel getFollowModel() const { return *resource.follow_model; }
inline const std::string &getScrollAction() const { return *resource.scroll_action; }
inline const bool getScrollReverse() const { return *resource.scroll_reverse; }
inline const bool getDefaultExternalTabs() const { return *resource.default_external_tabs; }
inline const bool getDefaultInternalTabs() const { return *resource.default_internal_tabs; }
inline Slit *slit() { return m_slit.get(); }
inline const Slit *slit() const { return m_slit.get(); }
@ -203,6 +205,7 @@ public:
void update(FbTk::Subject *subj);
FbTk::Menu *createMenu(const std::string &label);
FbTk::Menu *createToggleMenu(const std::string &label);
void hideMenus();
// for extras to add menus.
// These menus will be marked internal,
@ -218,6 +221,8 @@ public:
void setRootColormapInstalled(bool r) { root_colormap_installed = r; }
void saveRootCommand(std::string rootcmd) { *resource.rootcommand = rootcmd; }
void saveTabPlacement(FbWinFrame::TabPlacement place) { *resource.tab_placement = place; }
void saveWorkspaces(int w) { *resource.workspaces = w; }
void saveMenu(FbTk::Menu &menu) { m_rootmenu_list.push_back(&menu); }
@ -275,6 +280,7 @@ public:
void reconfigure();
void reconfigureTabs();
void rereadMenu();
void shutdown();
/// show position window centered on the screen with "X x Y" text
@ -434,6 +440,7 @@ private:
antialias, auto_raise, click_raises, decorate_transient;
FbTk::Resource<std::string> rootcommand;
FbTk::Resource<ResizeModel> resize_model;
FbTk::Resource<FbWinFrame::TabPlacement> tab_placement;
FbTk::Resource<std::string> windowmenufile;
FbTk::Resource<FollowModel> follow_model;
bool ordered_dither;
@ -447,7 +454,7 @@ private:
FbTk::Resource<FbTk::GContext::CapStyle> gc_cap_style;
FbTk::Resource<std::string> scroll_action;
FbTk::Resource<bool> scroll_reverse;
FbTk::Resource<bool> default_external_tabs;
FbTk::Resource<bool> default_internal_tabs;
} resource;

View file

@ -394,10 +394,11 @@ void FluxboxWindow::init() {
frame().setUseShape(!m_shaped);
if (screen().getDefaultExternalTabs()) {
frame().setTabMode(FbWinFrame::EXTERNAL);
} else {
frame().setTabPlacement(screen().getTabPlacement());
if (screen().getDefaultInternalTabs()) {
frame().setTabMode(FbWinFrame::INTERNAL);
} else {
frame().setTabMode(FbWinFrame::EXTERNAL);
}
//!! TODO init of client should be better
@ -3049,20 +3050,28 @@ void FluxboxWindow::setDecoration(Decoration decoration, bool apply) {
case DECOR_NORMAL:
decorations.titlebar = decorations.border = decorations.handle =
decorations.iconify = decorations.maximize =
decorations.menu = true;
decorations.menu = decorations.tab = true;
functions.resize = functions.move = functions.iconify =
functions.maximize = true;
break;
case DECOR_TAB:
decorations.border = decorations.iconify = decorations.maximize =
decorations.menu = decorations.tab = true;
decorations.titlebar = decorations.handle = false;
functions.resize = functions.move = functions.iconify =
functions.maximize = true;
break;
case DECOR_TINY:
decorations.titlebar = decorations.iconify = decorations.menu =
functions.move = functions.iconify = true;
functions.move = functions.iconify = decorations.tab = true;
decorations.border = decorations.handle = decorations.maximize =
functions.resize = functions.maximize = false;
break;
case DECOR_TOOL:
decorations.titlebar = decorations.menu = functions.move = true;
decorations.titlebar = decorations.tab = decorations.menu = functions.move = true;
decorations.iconify = decorations.border = decorations.handle =
decorations.maximize = functions.resize = functions.maximize =
functions.iconify = false;
@ -3110,7 +3119,7 @@ void FluxboxWindow::applyDecorations(bool initial) {
if (decorations.titlebar) {
bool change = frame().showTitlebar();
client_move |= change;
if (change && !screen().getDefaultExternalTabs()) {
if (change && screen().getDefaultInternalTabs()) {
client_move |= frame().setTabMode(FbWinFrame::INTERNAL);
}
} else {
@ -3357,42 +3366,56 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) {
int right = orig_left + width() + 2 * borderW;
int bottom = orig_top + height() + 2 * borderW;
// test against tabs too
bool i_have_tabs = frame().externalTabMode();
int xoff,yoff,woff,hoff;
if (i_have_tabs) {
xoff = xOffset();
yoff = yOffset();
woff = widthOffset();
hoff = heightOffset();
}
/////////////////////////////////////
// begin by checking the screen (or Xinerama head) edges
int h;
if (screen().numHeads() > 0) {
// head "0" == whole screen width + height, which we skip since the
// sum of all the heads covers those edges
for (h = 1; h <= screen().numHeads(); h++) {
snapToWindow(dx, dy, left, right, top, bottom,
int starth = 0;
// head "0" == whole screen width + height, which we skip since the
// sum of all the heads covers those edges, if >1 head
if (screen().numHeads() > 0)
starth=1;
for (int h=starth; h <= screen().numHeads(); h++) {
snapToWindow(dx, dy, left, right, top, bottom,
screen().maxLeft(h),
screen().maxRight(h),
screen().maxTop(h),
screen().maxBottom(h));
if (i_have_tabs)
snapToWindow(dx, dy, left - xoff, right - xoff + woff, top - yoff, bottom - yoff + hoff,
screen().maxLeft(h),
screen().maxRight(h),
screen().maxTop(h),
screen().maxBottom(h));
}
for (h = 1; h <= screen().numHeads(); h++) {
snapToWindow(dx, dy, left, right, top, bottom,
}
for (int h=starth; h <= screen().numHeads(); h++) {
snapToWindow(dx, dy, left, right, top, bottom,
screen().getHeadX(h),
screen().getHeadX(h) + screen().getHeadWidth(h),
screen().getHeadY(h),
screen().getHeadY(h) + screen().getHeadHeight(h));
if (i_have_tabs)
snapToWindow(dx, dy, left - xoff, right - xoff + woff, top - yoff, bottom - yoff + hoff,
screen().getHeadX(h),
screen().getHeadX(h) + screen().getHeadWidth(h),
screen().getHeadY(h),
screen().getHeadY(h) + screen().getHeadHeight(h));
}
} else {
snapToWindow(dx, dy, left, right, top, bottom,
screen().maxLeft(0),
screen().maxRight(0),
screen().maxTop(0),
screen().maxBottom(0));
snapToWindow(dx, dy, left, right, top, bottom,
screen().getHeadX(0),
screen().getHeadX(0) + screen().getHeadWidth(0),
screen().getHeadY(0),
screen().getHeadY(0) + screen().getHeadHeight(0));
}
/////////////////////////////////////
// now check window edges
@ -3415,6 +3438,30 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) {
(*it)->x() + (*it)->width() + 2 * bw,
(*it)->y(),
(*it)->y() + (*it)->height() + 2 * bw);
if (i_have_tabs)
snapToWindow(dx, dy, left - xoff, right - xoff + woff, top - yoff, bottom - yoff + hoff,
(*it)->x(),
(*it)->x() + (*it)->width() + 2 * bw,
(*it)->y(),
(*it)->y() + (*it)->height() + 2 * bw);
// also snap to the box containing the tabs (don't bother with actual
// tab edges, since they're dynamic
if ((*it)->frame().externalTabMode())
snapToWindow(dx, dy, left, right, top, bottom,
(*it)->x() - (*it)->xOffset(),
(*it)->x() - (*it)->xOffset() + (*it)->width() + 2 * bw + (*it)->widthOffset(),
(*it)->y() - (*it)->yOffset(),
(*it)->y() - (*it)->yOffset() + (*it)->height() + 2 * bw + (*it)->heightOffset());
if (i_have_tabs)
snapToWindow(dx, dy, left - xoff, right - xoff + woff, top - yoff, bottom - yoff + hoff,
(*it)->x() - (*it)->xOffset(),
(*it)->x() - (*it)->xOffset() + (*it)->width() + 2 * bw + (*it)->widthOffset(),
(*it)->y() - (*it)->yOffset(),
(*it)->y() - (*it)->yOffset() + (*it)->height() + 2 * bw + (*it)->heightOffset());
}
// commit

View file

@ -62,7 +62,8 @@ public:
DECOR_NONE=0, ///< no decor at all
DECOR_NORMAL, ///< normal normal
DECOR_TINY, ///< tiny decoration
DECOR_TOOL ///< decor tool
DECOR_TOOL, ///< decor tool
DECOR_TAB ///< decor tab (border + tab)
};
/// Motif wm Hints