all repos — fluxbox @ 3bde5c8aee16f7f33e3ce7b9058fded916fe2369

custom fork of the fluxbox windowmanager

Improve stretching (RELATIVE) toolbar items

The available space is distributed reg. the preferred width
of items (spacers and the iconbar ;-) instead of evenly.

The preferred width of the iconbar is calculated from its buttons.

This allows to align the iconbar using spacers and makes better use of
the available space
Thomas Lübking thomas.luebking@gmail.com
commit

3bde5c8aee16f7f33e3ce7b9058fded916fe2369

parent

10e3f10b55fbd8f3ff6793a3993b8ee55f3192a2

5 files changed, 45 insertions(+), 20 deletions(-)

jump to
M src/IconbarTool.ccsrc/IconbarTool.cc

@@ -292,7 +292,9 @@ }

void IconbarTool::resize(unsigned int width, unsigned int height) { m_icon_container.resize(width, height); - m_icon_container.setMaxTotalSize(m_icon_container.orientation() == FbTk::ROT0 || m_icon_container.orientation() == FbTk::ROT180 ? width : height); + const unsigned int maxsize = (m_icon_container.orientation() & 1) ? height : width; + m_icon_container.setMaxTotalSize(maxsize); + m_icon_container.setMaxSizePerClient(maxsize/std::max(1, m_icon_container.size())); renderTheme(); }

@@ -300,7 +302,9 @@ void IconbarTool::moveResize(int x, int y,

unsigned int width, unsigned int height) { m_icon_container.moveResize(x, y, width, height); - m_icon_container.setMaxTotalSize(m_icon_container.orientation() == FbTk::ROT0 || m_icon_container.orientation() == FbTk::ROT180 ? width : height); + const unsigned int maxsize = (m_icon_container.orientation() & 1) ? height : width; + m_icon_container.setMaxTotalSize(maxsize); + m_icon_container.setMaxSizePerClient(maxsize/std::max(1, m_icon_container.size())); renderTheme(); }

@@ -362,6 +366,18 @@ unsigned int IconbarTool::width() const {

return m_icon_container.width(); } +unsigned int IconbarTool::preferredWidth() const { + // border and paddings + unsigned int w = 2*borderWidth() + *m_rc_client_padding * m_icons.size(); + + // the buttons + for (IconMap::const_iterator it = m_icons.begin(), end = m_icons.end(); it != end; ++it) { + w += it->second->preferredWidth(); + } + + return w; +} + unsigned int IconbarTool::height() const { return m_icon_container.height(); }

@@ -384,9 +400,6 @@ }

m_icon_container.setAlignment(*m_rc_alignment); - *m_rc_client_width = FbTk::Util::clamp(*m_rc_client_width, 10, 400); - m_icon_container.setMaxSizePerClient(*m_rc_client_width); - // lock graphic update m_icon_container.setUpdateLock(true);

@@ -403,6 +416,11 @@ break;

case ALIGN: break; } + + resizeSig().emit(); + const unsigned int maxsize = (m_icon_container.orientation() & 1) ? height() : width(); + m_icon_container.setMaxTotalSize(maxsize); + m_icon_container.setMaxSizePerClient(maxsize/std::max(1, m_icon_container.size())); // unlock container and update graphics m_icon_container.setUpdateLock(false);

@@ -441,6 +459,7 @@ pos++;

} m_icon_container.insertItem(button, pos); + m_tracker.join(button->titleChanged(), FbTk::MemFun(resizeSig(), &FbTk::Signal<>::emit)); } void IconbarTool::reset() {
M src/IconbarTool.hhsrc/IconbarTool.hh

@@ -60,6 +60,7 @@ void setMode(std::string mode);

void parentMoved() { m_icon_container.parentMoved(); } unsigned int width() const; + unsigned int preferredWidth() const; unsigned int height() const; unsigned int borderWidth() const;
M src/Toolbar.ccsrc/Toolbar.cc

@@ -868,6 +868,8 @@ ItemList::iterator item_it = m_item_list.begin();

ItemList::iterator item_it_end = m_item_list.end(); int bevel_width = theme()->bevelWidth(); int fixed_width = bevel_width; // combined size of all fixed items + int relative_width = 0; // combined *desired* size of all relative items + int stretch_items = 0; int relative_items = 0; int last_bw = 0; // we show the largest border of adjoining items bool first = true;

@@ -895,7 +897,7 @@ }

last_bw = borderW; - tmpw = (*item_it)->width(); + tmpw = (*item_it)->preferredWidth(); tmph = (*item_it)->height(); FbTk::translateSize(orient, tmpw, tmph);

@@ -906,18 +908,22 @@ fixed_width += height;

if (bevel_width) fixed_width -= 2*(borderW + bevel_width); } else { - relative_items++; + ++relative_items; + relative_width += tmpw; + if (!tmpw) + ++stretch_items; } } // calculate what's going to be left over to the relative sized items - int relative_width = 0; - int rounding_error = 0; - if (relative_items == 0) - relative_width = 0; - else { // size left after fixed items / number of relative items - relative_width = (width - fixed_width) / relative_items; - rounding_error = width - fixed_width - relative_items * relative_width; + float stretch_factor = 1.0f; + if (relative_items) { + if (relative_width <= width - fixed_width && stretch_items) { + relative_width = int(width - fixed_width - relative_width)/stretch_items; + } else { + stretch_factor = float(width - fixed_width)/relative_width; + relative_width = 0; + } } // now move and resize the items

@@ -952,12 +958,9 @@ int tmpx = next_x + offset,

tmpy = offset; if ((*item_it)->type() == ToolbarItem::RELATIVE) { - int extra = 0; - if (rounding_error != 0) { // distribute rounding error over all relatives - extra = 1; - --rounding_error; - } - tmpw = extra + relative_width; + unsigned int itemw = (*item_it)->preferredWidth(), itemh = (*item_it)->height(); + FbTk::translateSize(orient, itemw, itemh); + tmpw = itemw ? std::floor(stretch_factor * itemw) : relative_width; tmph = height - size_offset; } else if ((*item_it)->type() == ToolbarItem::SQUARE) { tmpw = tmph = height - size_offset;
M src/ToolbarItem.hhsrc/ToolbarItem.hh

@@ -47,6 +47,7 @@

virtual void show() = 0; virtual void hide() = 0; virtual unsigned int width() const = 0; + virtual unsigned int preferredWidth() const { return width(); } virtual unsigned int height() const = 0; virtual unsigned int borderWidth() const = 0; // some items might be there, but effectively empty, so shouldn't appear
M src/Window.ccsrc/Window.cc

@@ -2804,6 +2804,7 @@

frame().setFocusTitle(title); // relay title to others that display the focus title titleSig().emit(title, *this); + frame().tabcontainer().repositionItems(); } void FluxboxWindow::frameExtentChanged() {