all repos — fluxbox @ c2ec3065f96c327b52082cf5f254a85b32eb938a

custom fork of the fluxbox windowmanager

change fbwinframe to use container
move a few frame ops to have most code in Container
simonb simonb
commit

c2ec3065f96c327b52082cf5f254a85b32eb938a

parent

e0e11dd32bd9f7eb717ec7ee9a3b1f08a677d7e4

5 files changed, 267 insertions(+), 267 deletions(-)

jump to
M ChangeLogChangeLog

@@ -1,5 +1,8 @@

(Format: Year/Month/Day) Changes for 0.9.14: +*05/06/19: + * Change FbWinFrame to use a Container (Simon) + FbWinFrame.hh/cc Container.hh/cc *05/06/18: * Fixes #1206821, unportable usage of grep in fbgm (thanx Dung) util/fluxbox-generate_menu.in
M src/Container.ccsrc/Container.cc

@@ -26,6 +26,7 @@ #include "Container.hh"

#include "FbTk/Button.hh" #include "FbTk/EventManager.hh" +#include "CompareWindow.hh" Container::Container(const FbTk::FbWindow &parent): FbTk::FbWindow(parent, 0, 0, 1, 1, ExposureMask),

@@ -111,10 +112,97 @@

repositionItems(); } -void Container::removeItem(int index) { - if (index < 0 || index > size()) +void Container::moveItem(Item item, int movement) { + int index = find(item); + if (index < 0) return; + int size = m_item_list.size(); + int newindex = (index + movement) % size; + if (newindex < 0) // neg wrap + newindex += size; + + if (newindex > index) // one smaller now + --newindex; + + ItemList::iterator it = m_item_list.begin(); + for (; newindex > 0 && index > 0; ++it, --newindex, --index) { + if (newindex == 0) { + m_item_list.insert(it, item); + ++newindex; + } + + if (index == 0) { + m_item_list.erase(it); + --index; + } + } + + m_item_list.insert(it, item); + insertItem(item, newindex); + repositionItems(); + +} + +// returns true if something was done +bool Container::moveItemTo(Item item, int x, int y) { + Window parent_return=0, + root_return=0, + *children_return = NULL; + + unsigned int nchildren_return; + + // get the root window + if (!XQueryTree(display(), window(), + &root_return, &parent_return, &children_return, &nchildren_return)) + parent_return = parent_return; + + if (children_return != NULL) + XFree(children_return); + + int dest_x = 0, dest_y = 0; + Window itemwin = 0; + if (!XTranslateCoordinates(display(), + root_return, window(), + x, y, &dest_x, &dest_y, + &itemwin)) + return false; + + ItemList::iterator it = find_if(m_item_list.begin(), + m_item_list.end(), + CompareWindow(&FbTk::FbWindow::window, + itemwin)); + // not found :( + if (it == m_item_list.end()) + return false; + + Window child_return = 0; + //make x and y relative to our item + if (!XTranslateCoordinates(display(), + window(), itemwin, + dest_x, dest_y, &x, &y, + &child_return)) + return false; + return true; +} + +bool Container::removeItem(Item item) { + ItemList::iterator it = m_item_list.begin(); + ItemList::iterator it_end = m_item_list.end(); + for (; it != it_end && (*it) != item; ++it); + + if (it == it_end) + return false; + + m_item_list.erase(it); + repositionItems(); + return true; +} + +bool Container::removeItem(int index) { + if (index < 0 || index > size()) + return false; + ItemList::iterator it = m_item_list.begin(); for (; index != 0; ++it, --index) continue;

@@ -125,6 +213,7 @@

m_item_list.erase(it); repositionItems(); + return true; } void Container::removeAll() {

@@ -136,7 +225,7 @@ }

} -int Container::find(Item item) { +int Container::find(ConstItem item) { ItemList::iterator it = m_item_list.begin(); ItemList::iterator it_end = m_item_list.end(); int index = 0;

@@ -178,6 +267,60 @@ clearArea(event.x, event.y, event.width, event.height);

} } +bool Container::tryExposeEvent(XExposeEvent &event) { + if (event.window == window()) { + exposeEvent(event); + return true; + } + + ItemList::iterator it = find_if(m_item_list.begin(), + m_item_list.end(), + CompareWindow(&FbTk::FbWindow::window, + event.window)); + // not found :( + if (it == m_item_list.end()) + return false; + + (*it)->exposeEvent(event); + return true; +} + +bool Container::tryButtonPressEvent(XButtonEvent &event) { + if (event.window == window()) { + // we don't have a buttonrelease event atm + return true; + } + + ItemList::iterator it = find_if(m_item_list.begin(), + m_item_list.end(), + CompareWindow(&FbTk::FbWindow::window, + event.window)); + // not found :( + if (it == m_item_list.end()) + return false; + + (*it)->buttonPressEvent(event); + return true; +} + +bool Container::tryButtonReleaseEvent(XButtonEvent &event) { + if (event.window == window()) { + // we don't have a buttonrelease event atm + return true; + } + + ItemList::iterator it = find_if(m_item_list.begin(), + m_item_list.end(), + CompareWindow(&FbTk::FbWindow::window, + event.window)); + // not found :( + if (it == m_item_list.end()) + return false; + + (*it)->buttonReleaseEvent(event); + return true; +} + void Container::repositionItems() { if (empty() || m_update_lock) return;

@@ -241,3 +384,24 @@

// this will never happen anyway return 1; } + +void Container::for_each(std::mem_fun_t<void, FbTk::FbWindow> function) { + std::for_each(m_item_list.begin(), + m_item_list.end(), + function); +} + +void Container::setAlpha(unsigned char alpha) { + ItemList::iterator it = m_item_list.begin(); + ItemList::iterator it_end = m_item_list.end(); + for (; it != it_end; ++it) + (*it)->setAlpha(alpha); +} + +void Container::clear() { + ItemList::iterator it = m_item_list.begin(); + ItemList::iterator it_end = m_item_list.end(); + for (; it != it_end; ++it) + (*it)->clear(); + +}
M src/Container.hhsrc/Container.hh

@@ -25,7 +25,7 @@

#ifndef CONTAINER_HH #define CONTAINER_HH -#include "FbTk/FbWindow.hh" +#include "FbTk/Button.hh" #include "FbTk/EventHandler.hh" #include "FbTk/NotCopyable.hh"

@@ -34,7 +34,8 @@

class Container:public FbTk::FbWindow, public FbTk::EventHandler, private FbTk::NotCopyable { public: enum Alignment { LEFT, RELATIVE, RIGHT }; - typedef FbTk::FbWindow * Item; + typedef FbTk::Button * Item; + typedef const FbTk::Button * ConstItem; typedef std::list<Item> ItemList; explicit Container(const FbTk::FbWindow &parent);

@@ -48,9 +49,12 @@ unsigned int width, unsigned int height);

void insertItems(ItemList &list, int position=-1); void insertItem(Item item, int pos = -1); - void removeItem(int item); + bool removeItem(int item); // return true if something was removed + bool removeItem(Item item); // return true if something was removed void removeAll(); - int find(Item item); + void moveItem(Item item, int movement); // wraps around + bool moveItemTo(Item item, int x, int y); + int find(ConstItem item); void setSelected(int index); void setMaxSizePerClient(unsigned int size); void setAlignment(Alignment a);

@@ -64,6 +68,10 @@ inline void setUpdateLock(bool value) { m_update_lock = value; }

/// event handler void exposeEvent(XExposeEvent &event); + // for use when embedded in something that may passthrough + bool tryExposeEvent(XExposeEvent &event); + bool tryButtonPressEvent(XButtonEvent &event); + bool tryButtonReleaseEvent(XButtonEvent &event); /// accessors inline Alignment alignment() const { return m_align; }

@@ -74,6 +82,14 @@ inline Item selected() { return m_selected; }

unsigned int maxWidthPerClient() const; inline unsigned int maxHeightPerClient() const { return (empty() ? height() : height()/size()); } inline bool updateLock() const { return m_update_lock; } + + void for_each(std::mem_fun_t<void, FbWindow> function); + void setAlpha(unsigned char alpha); // set alpha on all windows + + ItemList::iterator begin() { return m_item_list.begin(); } + ItemList::iterator end() { return m_item_list.end(); } + + void clear(); // clear all windows private: void repositionItems();
M src/FbWinFrame.ccsrc/FbWinFrame.cc

@@ -34,6 +34,8 @@ #include "CompareWindow.hh"

#include "FbWinFrameTheme.hh" #include "fluxbox.hh" +#include "Container.hh" + #ifdef SHAPE #include "Shape.hh" #endif // SHAPE

@@ -56,10 +58,13 @@ m_titlebar(m_window, 0, 0, 100, 16,

ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | ExposureMask | EnterWindowMask | LeaveWindowMask), + m_tab_container(m_titlebar), +/* m_label(m_titlebar, 0, 0, 100, 16, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | ExposureMask | EnterWindowMask | LeaveWindowMask), +*/ m_handle(m_window, 0, 0, 100, 5, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | ExposureMask |

@@ -82,6 +87,7 @@ m_use_handle(true),

m_focused(false), m_visible(false), m_button_pm(0), + m_tabmode(INTERNAL), // TODO: configurable default (on compile, for backwards compat) m_need_render(true), m_themelistener(*this), m_shape(new Shape(m_window, theme.shapePlace())) {

@@ -221,7 +227,8 @@ return;

if (m_use_titlebar) { m_titlebar.parentMoved(); - m_label.parentMoved(); + //m_label.parentMoved(); + m_tab_container.parentMoved(); for_each(m_buttons_left.begin(), m_buttons_left.end(),

@@ -229,9 +236,7 @@ mem_fun(&FbTk::Button::parentMoved));

for_each(m_buttons_right.begin(), m_buttons_right.end(), mem_fun(&FbTk::Button::parentMoved)); - for_each(m_labelbuttons.begin(), - m_labelbuttons.end(), - mem_fun(&FbTk::Button::parentMoved)); + m_tab_container.for_each(mem_fun(&FbTk::Button::parentMoved)); } if (m_use_handle) {

@@ -276,13 +281,7 @@ unsigned char alpha = (m_focused?theme().focusedAlpha():theme().unfocusedAlpha());

if (FbTk::Transparent::haveComposite()) { m_window.setOpaque(alpha); } else { - LabelList::iterator btn_it = m_labelbuttons.begin(); - LabelList::iterator btn_it_end = m_labelbuttons.end(); - for (; btn_it != btn_it_end; ++btn_it) { - (*btn_it)->setAlpha(alpha); - if (m_current_label != (*btn_it)) - (*btn_it)->updateBackground(false); - } + m_tab_container.setAlpha(alpha); } }

@@ -334,13 +333,15 @@ }

} FbWinFrame::ButtonId FbWinFrame::createTab(const std::string &title, FbTk::Command *command) { - FbTk::TextButton *button = new FbTk::TextButton(label(), + FbTk::TextButton *button = new FbTk::TextButton(m_tab_container, theme().font(), title); + button->show(); button->setEventMask(ExposureMask | ButtonPressMask | - ButtonReleaseMask | ButtonMotionMask | + ButtonReleaseMask | ButtonMotionMask | EnterWindowMask); + FbTk::EventManager::instance()->add(*button, button->window()); FbTk::RefCount<FbTk::Command> refcmd(command); button->setOnClick(refcmd);

@@ -348,7 +349,7 @@

button->setTextPadding(Fluxbox::instance()->getTabsPadding()); button->setJustify(theme().justify()); - m_labelbuttons.push_back(button); + m_tab_container.insertItem(button); if (currentLabel() == 0) setLabelButtonFocus(*button);

@@ -357,162 +358,47 @@ return button;

} void FbWinFrame::removeTab(ButtonId btn) { - LabelList::iterator erase_it = remove(m_labelbuttons.begin(), - m_labelbuttons.end(), - btn); - if (erase_it == m_labelbuttons.end()) - return; - if (btn == m_current_label) m_current_label = 0; - m_labelbuttons.erase(erase_it); - delete btn; + if (m_tab_container.removeItem(btn)) + delete btn; + } -void FbWinFrame::moveLabelButtonLeft(const FbTk::TextButton &btn) { - LabelList::iterator it = find(m_labelbuttons.begin(), - m_labelbuttons.end(), - &btn); - // make sure we found it and we're not at the begining - if (it == m_labelbuttons.end() || it == m_labelbuttons.begin()) - return; - - LabelList::iterator new_pos = it; - new_pos--; - FbTk::TextButton *item = *it; - // remove from list - m_labelbuttons.erase(it); - // insert on the new place - m_labelbuttons.insert(new_pos, item); - // update titlebar - redrawTitlebar(); +void FbWinFrame::moveLabelButtonLeft(FbTk::TextButton &btn) { + m_tab_container.moveItem(&btn, -1); } -void FbWinFrame::moveLabelButtonRight(const FbTk::TextButton &btn) { - LabelList::iterator it = find(m_labelbuttons.begin(), - m_labelbuttons.end(), - &btn); - // make sure we found it and we're not at the last item - if (it == m_labelbuttons.end() || *it == m_labelbuttons.back()) - return; - - FbTk::TextButton *item = *it; - // remove from list - LabelList::iterator new_pos = m_labelbuttons.erase(it); - new_pos++; - // insert on the new place - m_labelbuttons.insert(new_pos, item); - // update titlebar - redrawTitlebar(); +void FbWinFrame::moveLabelButtonRight(FbTk::TextButton &btn) { + m_tab_container.moveItem(&btn, -1); } void FbWinFrame::moveLabelButtonTo(FbTk::TextButton &btn, int x, int y) { - Window parent_return=0, - root_return=75, - *children_return = NULL; - - unsigned int nchildren_return; - - // get the root window - if (!XQueryTree(window().display(), window().window(), - &root_return, &parent_return, &children_return, &nchildren_return)) - parent_return = parent_return; - - if (children_return != NULL) - XFree(children_return); - - int dest_x = 0, dest_y = 0; - Window labelbutton = 0; - if (!XTranslateCoordinates(window().display(), - root_return, label().window(), - x, y, &dest_x, &dest_y, - &labelbutton)) - return; - - LabelList::iterator it = find_if(m_labelbuttons.begin(), - m_labelbuttons.end(), - CompareWindow(&FbTk::Button::window, - labelbutton)); - // label button not found - if (it == m_labelbuttons.end()) - return; - - Window child_return = 0; - //make x and y relative to our labelbutton - if (!XTranslateCoordinates(window().display(), - label().window(),labelbutton, - dest_x, dest_y, &x, &y, - &child_return)) - return; - - if (x > (*it)->width() / 2) - moveLabelButtonRightOf(btn,**it); - else - moveLabelButtonLeftOf(btn,**it); - + m_tab_container.moveItemTo(&btn, x, y); } -void FbWinFrame::moveLabelButtonLeftOf(const FbTk::TextButton &btn, const FbTk::TextButton &dest) { - LabelList::iterator it = find(m_labelbuttons.begin(), - m_labelbuttons.end(), - &btn); - LabelList::iterator new_pos = find(m_labelbuttons.begin(), - m_labelbuttons.end(), - &dest); - - // make sure we found them - if (it == m_labelbuttons.end() || new_pos == m_labelbuttons.end()) - return; - - // moving a button to the left of itself results in no change - if (new_pos == it) +void FbWinFrame::moveLabelButtonLeftOf(FbTk::TextButton &btn, const FbTk::TextButton &dest) { + int pos = m_tab_container.find(&dest); + if (pos < 0) return; - FbTk::TextButton *item = *it; - // remove from list - m_labelbuttons.erase(it); - // insert on the new place - m_labelbuttons.insert(new_pos, item); - // update titlebar - redrawTitlebar(); + m_tab_container.moveItem(&btn, pos-1); } -void FbWinFrame::moveLabelButtonRightOf(const FbTk::TextButton &btn, const FbTk::TextButton &dest) { - LabelList::iterator it = find(m_labelbuttons.begin(), - m_labelbuttons.end(), - &btn); - LabelList::iterator new_pos = find(m_labelbuttons.begin(), - m_labelbuttons.end(), - &dest); - - // make sure we found them - if (it == m_labelbuttons.end() || new_pos == m_labelbuttons.end()) +void FbWinFrame::moveLabelButtonRightOf(FbTk::TextButton &btn, const FbTk::TextButton &dest) { + int pos = m_tab_container.find(&dest); + if (pos < 0) return; - //moving a button to the right of itself results in no change - if (new_pos == it) - return; - - FbTk::TextButton *item = *it; - // remove from list - m_labelbuttons.erase(it); - // need to insert into the next position - new_pos++; - // insert on the new place - if (new_pos == m_labelbuttons.end()) - m_labelbuttons.push_back(item); - else - m_labelbuttons.insert(new_pos, item); - //update titlebar - redrawTitlebar(); + m_tab_container.moveItem(&btn, pos-1); } void FbWinFrame::setLabelButtonFocus(FbTk::TextButton &btn) { - if (&btn == currentLabel() || btn.parent() != &label()) + if (&btn == currentLabel() || btn.parent() != &m_tab_container) return; // render label buttons

@@ -658,7 +544,7 @@ */

void FbWinFrame::setEventHandler(FbTk::EventHandler &evh) { FbTk::EventManager &evm = *FbTk::EventManager::instance(); - evm.add(evh, m_label); + evm.add(evh, m_tab_container); evm.add(evh, m_titlebar); evm.add(evh, m_handle); evm.add(evh, m_grip_right);

@@ -672,7 +558,7 @@ remove event handler from windows

*/ void FbWinFrame::removeEventHandler() { FbTk::EventManager &evm = *FbTk::EventManager::instance(); - evm.remove(m_label); + evm.remove(m_tab_container); evm.remove(m_titlebar); evm.remove(m_handle); evm.remove(m_grip_right);

@@ -683,14 +569,7 @@ }

void FbWinFrame::buttonPressEvent(XButtonEvent &event) { // we can ignore which window the event was generated for - LabelList::iterator btn_it = m_labelbuttons.begin(); - LabelList::iterator btn_it_end = m_labelbuttons.end(); - for (; btn_it != btn_it_end; ++btn_it) { - if ((*btn_it)->window() == event.window) { - (*btn_it)->buttonPressEvent(event); - break; - } - } + m_tab_container.tryButtonPressEvent(event); if (event.window == m_grip_right.window() || event.window == m_grip_left.window() || event.window == m_clientarea.window() ||

@@ -707,12 +586,8 @@

void FbWinFrame::buttonReleaseEvent(XButtonEvent &event) { // we can ignore which window the event was generated for - LabelList::iterator button_it = find_if(m_labelbuttons.begin(), - m_labelbuttons.end(), - CompareWindow(&FbTk::Button::window, - event.window)); - if (button_it != m_labelbuttons.end()) - (*button_it)->buttonReleaseEvent(event); + // we continue even if a button got the event + m_tab_container.tryButtonReleaseEvent(event); if (event.window == m_grip_right.window() || event.window == m_grip_left.window() ||

@@ -739,8 +614,8 @@

void FbWinFrame::exposeEvent(XExposeEvent &event) { if (m_titlebar == event.window) { m_titlebar.clearArea(event.x, event.y, event.width, event.height); - } else if (m_label == event.window) { - m_label.clearArea(event.x, event.y, event.width, event.height); + } else if (m_tab_container == event.window) { + m_tab_container.clearArea(event.x, event.y, event.width, event.height); } else if (m_handle == event.window) { m_handle.clearArea(event.x, event.y, event.width, event.height); } else if (m_grip_left == event.window) {

@@ -748,18 +623,14 @@ m_grip_left.clearArea(event.x, event.y, event.width, event.height);

} else if (m_grip_right == event.window) { m_grip_right.clearArea(event.x, event.y, event.width, event.height); } else { + + if (m_tab_container.tryExposeEvent(event)) + return; + // create compare function // that we should use with find_if FbTk::CompareEqual_base<FbTk::FbWindow, Window> compare(&FbTk::FbWindow::window, event.window); - - LabelList::iterator btn_it = find_if(m_labelbuttons.begin(), - m_labelbuttons.end(), - compare); - if (btn_it != m_labelbuttons.end()) { - (*btn_it)->exposeEvent(event); - return; - } ButtonList::iterator it = find_if(m_buttons_left.begin(), m_buttons_left.end(),

@@ -789,7 +660,7 @@ resize(event.width, event.height);

} void FbWinFrame::reconfigure() { - if (m_labelbuttons.empty()) + if (m_tab_container.empty()) return; m_bevel = theme().bevelWidth();

@@ -902,73 +773,12 @@ /**

aligns and redraws title */ void FbWinFrame::redrawTitlebar() { - if (!m_use_titlebar || m_labelbuttons.empty()) + if (!m_use_titlebar || m_tab_container.empty()) return; - int focus_button_min_percent = Fluxbox::instance()->getFocusedTabMinWidth(); - int button_count = m_labelbuttons.size(); - int label_width = label().width(); - - /* force sane value */ - if (focus_button_min_percent > 90) - focus_button_min_percent = 90; - if (focus_button_min_percent < 1) - focus_button_min_percent = 1; - - int focus_button_width, unfocus_button_width; - if (100 < (focus_button_min_percent * button_count)) { - focus_button_width = label_width * focus_button_min_percent / 100; - if (button_count > 1) { - unfocus_button_width = label_width * - (100 - focus_button_min_percent) / (100 * (button_count - 1)); - } else { - /* should never happen */ - unfocus_button_width = 0; - } - } else { - focus_button_width = label_width / button_count; - unfocus_button_width = focus_button_width; - } - - int rounding_error = label_width - focus_button_width - - ((button_count - 1) * unfocus_button_width); - - //!! TODO: bevel - //int border_width = m_labelbuttons.front()->window().borderWidth(); - int border_width = m_labelbuttons.empty() ? 0 : m_labelbuttons.front()->borderWidth(); - - LabelList::iterator btn_it = m_labelbuttons.begin(); - LabelList::iterator btn_it_end = m_labelbuttons.end(); - int extra = 0, dx = 0; - for (unsigned int last_x = 0; - btn_it != btn_it_end; - ++btn_it, last_x += dx) { - - if (rounding_error != 0) { - extra = 1; - --rounding_error; - } else - extra = 0; - - if (currentLabel() == *btn_it) { - dx = focus_button_width; - } else { - dx = unfocus_button_width; - } - dx += border_width + extra; - - (*btn_it)->moveResize(last_x - border_width, - border_width, - dx - border_width, - label().height() + border_width); - - } - if (isVisible()) { - for_each(m_labelbuttons.begin(), - m_labelbuttons.end(), - mem_fun(&FbTk::TextButton::clear)); - - m_label.clear(); + m_tab_container.clear(); + //m_label.clear(); m_titlebar.clear(); } }

@@ -1011,10 +821,10 @@ space_left -= m_buttons_right.size() * (button_size + m_bevel);

space_left -= m_bevel; - m_label.moveResize(next_x, m_bevel, - space_left, button_size); + m_tab_container.moveResize(next_x, m_bevel, + space_left, button_size); - next_x += m_label.width() + m_bevel;; + next_x += m_tab_container.width() + m_bevel;; // finaly set new buttons to the right for (size_t i=0; i < m_buttons_right.size();

@@ -1060,12 +870,12 @@ m_titlebar.width(), m_titlebar.height());

render(m_theme.labelFocusTexture(), m_label_focused_color, m_label_focused_pm, - m_label.width(), m_label.height()); + m_tab_container.width(), m_tab_container.height()); render(m_theme.labelUnfocusTexture(), m_label_unfocused_color, m_label_unfocused_pm, - m_label.width(), m_label.height()); + m_tab_container.width(), m_tab_container.height()); renderButtons(); }

@@ -1082,12 +892,12 @@ label_color, title_color);

unsigned char alpha = (m_focused?theme().focusedAlpha():theme().unfocusedAlpha()); m_titlebar.setAlpha(alpha); - m_label.setAlpha(alpha); + m_tab_container.setAlpha(alpha); if (label_pm != 0) - m_label.setBackgroundPixmap(label_pm); + m_tab_container.setBackgroundPixmap(label_pm); else - m_label.setBackgroundColor(label_color); + m_tab_container.setBackgroundColor(label_color); if (title_pm != 0) m_titlebar.setBackgroundPixmap(title_pm);

@@ -1226,7 +1036,7 @@ m_button_size = 26;

m_clientarea.setBorderWidth(0); m_shaded = false; - m_label.show(); + m_tab_container.show(); showHandle(); showTitlebar();

@@ -1325,31 +1135,32 @@ }

render(m_theme.labelFocusTexture(), m_labelbutton_focused_color, m_labelbutton_focused_pm, - m_label.width(), m_label.height()); + m_tab_container.width(), m_tab_container.height()); render(m_theme.labelUnfocusTexture(), m_labelbutton_unfocused_color, m_labelbutton_unfocused_pm, - m_label.width(), m_label.height()); + m_tab_container.width(), m_tab_container.height()); render(m_theme.labelActiveTexture(), m_labelbutton_active_color, m_labelbutton_active_pm, - m_label.width(), m_label.height()); + m_tab_container.width(), m_tab_container.height()); } void FbWinFrame::applyLabelButtons() { - LabelList::iterator btn_it = m_labelbuttons.begin(); - LabelList::iterator btn_it_end = m_labelbuttons.end(); + Container::ItemList::iterator btn_it = m_tab_container.begin(); + Container::ItemList::iterator btn_it_end = m_tab_container.end(); for (; btn_it != btn_it_end; ++btn_it) { - if (*btn_it == m_current_label) { + FbTk::TextButton *btn = static_cast<FbTk::TextButton *>(*btn_it); + if (btn == m_current_label) { if (m_focused) - applyFocusLabel(**btn_it); + applyFocusLabel(*btn); else - applyActiveLabel(**btn_it); + applyActiveLabel(*btn); } else - applyUnfocusLabel(**btn_it); + applyUnfocusLabel(*btn); } }
M src/FbWinFrame.hhsrc/FbWinFrame.hh

@@ -30,6 +30,7 @@ #include "FbTk/RefCount.hh"

#include "FbTk/Observer.hh" #include "FbTk/Color.hh" #include "FbTk/FbPixmap.hh" +#include "Container.hh" #include <vector> #include <list>

@@ -51,6 +52,8 @@ /// holds a window frame with a client window

/// (see: <a href="fluxbox_fbwinframe.png">image</a>) class FbWinFrame:public FbTk::EventHandler { public: + enum TabMode { INTERNAL = 1, EXTERNAL }; + typedef FbTk::TextButton *ButtonId; ///< defines a button id /// create a top level window

@@ -112,15 +115,15 @@ // void addLabelButton(FbTk::TextButton &btn);

/// removes a specific button from label window void removeTab(ButtonId id); /// move label button to the left - void moveLabelButtonLeft(const FbTk::TextButton &btn); + void moveLabelButtonLeft(FbTk::TextButton &btn); /// move label button to the right - void moveLabelButtonRight(const FbTk::TextButton &btn); + void moveLabelButtonRight(FbTk::TextButton &btn); /// move label button to the given location( x and y are relative to the root window) void moveLabelButtonTo(FbTk::TextButton &btn, int x, int y); /// move the first label button to the left of the second - void moveLabelButtonLeftOf(const FbTk::TextButton &btn, const FbTk::TextButton &dest); + void moveLabelButtonLeftOf(FbTk::TextButton &btn, const FbTk::TextButton &dest); //move the first label button to the right of the second - void moveLabelButtonRightOf(const FbTk::TextButton &btn, const FbTk::TextButton &dest); + void moveLabelButtonRightOf(FbTk::TextButton &btn, const FbTk::TextButton &dest); /// which button is to be rendered focused void setLabelButtonFocus(FbTk::TextButton &btn); /// attach a client window for client area

@@ -252,6 +255,7 @@ */

//@{ FbTk::FbWindow m_window; ///< base window that holds each decorations (ie titlebar, handles) FbTk::FbWindow m_titlebar; ///< titlebar window + Container m_tab_container; ///< Holds tabs FbTk::FbWindow m_label; ///< holds title FbTk::FbWindow m_handle; ///< handle between grips FbTk::FbWindow m_grip_right, ///< rightgrip

@@ -262,7 +266,6 @@ typedef std::vector<FbTk::Button *> ButtonList;

ButtonList m_buttons_left, ///< buttons to the left m_buttons_right; ///< buttons to the right typedef std::list<FbTk::TextButton *> LabelList; - LabelList m_labelbuttons; ///< holds label buttons inside label window FbTk::TextButton *m_current_label; ///< which client button is focused at the moment std::string m_titletext; ///< text to be displayed int m_label int m_bevel; ///< bevel between titlebar items and titlebar

@@ -309,6 +312,8 @@ Pixmap m_grip_unfocused_pm; ///< unfocused pixmap for grip

FbTk::Color m_grip_unfocused_color; ///< unfocused color for grip if no pixmap is given //@} + TabMode m_tabmode; + bool m_need_render; int m_button_size; ///< size for all titlebar buttons unsigned int m_width_before_shade, ///< width before shade, so we can restore it when we unshade

@@ -334,6 +339,7 @@ };

ThemeListener m_themelistener; std::auto_ptr<Shape> m_shape; bool m_disable_shape; + }; #endif // FBWINFRAME_HH