external tabs

This commit is contained in:
simonb 2006-03-20 11:31:24 +00:00
parent eba0040373
commit f2d3fff4d4
20 changed files with 550 additions and 148 deletions

View file

@ -1,4 +1,17 @@
(Format: Year/Month/Day)
Changes for 0.9.16:
*06/03/20:
* External tabs (Simon)
- option in Configure menu to enable
- restart require at present when toggling this option
- New apps pnemonic for "Deco" option: TAB, which is like NONE,
but with an external tab
Notes:
- tab width currently hardcoded
- only alignment is topleft
fluxbox.cc Screen.hh/cc Window.hh/cc FbWinFrame.hh/cc Remember.cc
Container.hh/cc FbTk/XLayer.hh/cc XLayerItem.cc fluxbox-nls.hh
RowSmart/ColSmart/UnderMousePlacement.cc WinButton.cc
Changes for 0.9.15:
*06/03/19:
* Fixed some wrong fbsetroot nls (Thanks Semushin Slava )

View file

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

View file

@ -48,8 +48,11 @@ bool ColSmartPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowli
int test_x;
int win_w = win.width() + win.fbWindow().borderWidth()*2;
int win_h = win.height() + win.fbWindow().borderWidth()*2;
int win_w = win.width() + win.fbWindow().borderWidth()*2 + win.widthOffset();
int win_h = win.height() + win.fbWindow().borderWidth()*2 + win.heightOffset();
int x_off = win.xOffset();
int y_off = win.yOffset();
if (left_right)
test_x = head_left;
@ -87,10 +90,10 @@ bool ColSmartPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowli
std::vector<FluxboxWindow *>::const_iterator it_end =
windowlist.end();
for (; it != it_end && placed; ++it) {
int curr_x = (*it)->x();
int curr_y = (*it)->y();
int curr_w = (*it)->width() + (*it)->fbWindow().borderWidth()*2;
int curr_h = (*it)->height() + (*it)->fbWindow().borderWidth()*2;
int curr_x = (*it)->x() + (*it)->xOffset();
int curr_y = (*it)->y() + (*it)->yOffset();
int curr_w = (*it)->width() + (*it)->fbWindow().borderWidth()*2 + (*it)->widthOffset();
int curr_h = (*it)->height() + (*it)->fbWindow().borderWidth()*2 + (*it)->heightOffset();
if (curr_x < test_x + win_w &&
curr_x + curr_w > test_x &&
@ -122,8 +125,8 @@ bool ColSmartPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowli
}
if (placed) {
place_x = test_x;
place_y = test_y;
place_x = test_x + x_off;
place_y = test_y + y_off;
}
test_y = next_y;

View file

@ -34,6 +34,7 @@ Container::Container(const FbTk::FbWindow &parent):
FbTk::FbWindow(parent, 0, 0, 1, 1, ExposureMask),
m_align(RELATIVE),
m_max_size_per_client(60),
m_max_total_size(0),
m_selected(0),
m_update_lock(false) {
FbTk::EventManager::instance()->add(*this, *this);
@ -59,6 +60,13 @@ void Container::moveResize(int x, int y,
repositionItems();
}
/*
void Container::move(int x, int y) {
FbTk::FbWindow::move(x, y);
// no need to reposition
}
*/
void Container::insertItems(ItemList &item_list, int pos) {
// make sure all items have parent == this
@ -255,6 +263,33 @@ void Container::setMaxSizePerClient(unsigned int size) {
m_max_size_per_client = size;
}
void Container::setMaxTotalSize(unsigned int size) {
m_max_total_size = size;
if (m_max_total_size && width() > m_max_total_size) {
resize(m_max_total_size, height());
} else {
// this is a bit of duplication from repositionItems
// for when we are allowed to grow ourself
Alignment align = alignment();
unsigned int num_items = m_item_list.size();
if (m_max_total_size && (align == RIGHT || align == LEFT) &&
num_items) {
unsigned int max_width_per_client = maxWidthPerClient();
unsigned int borderW = m_item_list.front()->borderWidth();
unsigned int preferred_width = (max_width_per_client + borderW) * num_items - borderW;
if (preferred_width > m_max_total_size)
preferred_width = m_max_total_size;
if (preferred_width != width())
repositionItems();
}
}
}
void Container::setAlignment(Container::Alignment a) {
m_align = a;
}
@ -325,25 +360,48 @@ void Container::repositionItems() {
//!! TODO vertical position
const int max_width_per_client = maxWidthPerClient();
unsigned int max_width_per_client = maxWidthPerClient();
unsigned int borderW = m_item_list.front()->borderWidth();
unsigned int num_items = m_item_list.size();
unsigned int total_width = width();
// if we have a max total size, then we must also resize ourself
// within that bound
Alignment align = alignment();
if (m_max_total_size && (align == RIGHT || align == LEFT)) {
total_width = (max_width_per_client + borderW) * num_items - borderW;
if (total_width > m_max_total_size) {
total_width = m_max_total_size;
if (m_max_total_size > ((num_items - 1)*borderW)) { // don't go negative with unsigned nums
max_width_per_client = ( m_max_total_size - (num_items - 1)*borderW ) / num_items;
total_width = (max_width_per_client + borderW) * num_items - borderW;
} else
max_width_per_client = 1;
}
if (total_width != width()) {
// calling Container::resize here risks infinite loops
FbTk::FbWindow::resize(total_width, height());
}
}
ItemList::iterator it = m_item_list.begin();
const ItemList::iterator it_end = m_item_list.end();
int borderW = m_item_list.front()->borderWidth();
int rounding_error = width() - ((maxWidthPerClient() + borderW)* m_item_list.size() - borderW);
int rounding_error = total_width - ((max_width_per_client + borderW)* num_items - borderW);
int next_x = -borderW; // zero so the border of the first shows
int extra = 0;
int direction = 1;
if (alignment() == RIGHT) {
if (align == RIGHT) {
direction = -1;
next_x = 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)) {
// we only need to do error stuff with alignment RELATIVE
if (rounding_error != 0 && alignment() == RELATIVE) {
if (rounding_error != 0 && align == RELATIVE) {
--rounding_error;
extra = 1;
} else {
@ -374,7 +432,11 @@ unsigned int Container::maxWidthPerClient() const {
int borderW = m_item_list.front()->borderWidth();
// there're count-1 borders to fit in with the windows
// -> 1 per window plus end
return (width() - (count - 1) * borderW) / count;
unsigned int w = width();
if (w < (count-1)*borderW)
return 1;
else
return (w - (count - 1) * borderW) / count;
}
break;
}

View file

@ -25,15 +25,21 @@
#ifndef CONTAINER_HH
#define CONTAINER_HH
#include "FbTk/Button.hh"
#include "FbTk/FbWindow.hh"
#include "FbTk/EventHandler.hh"
#include "FbTk/NotCopyable.hh"
namespace FbTk {
class Button;
}
#include <list>
#include <functional>
class Container:public FbTk::FbWindow, public FbTk::EventHandler, private FbTk::NotCopyable {
public:
// LEFT, RIGHT => fixed total width, fixed icon size
// RELATIVE => fixed total width, relative/variable icon size
enum Alignment { LEFT, RELATIVE, RIGHT };
typedef FbTk::Button * Item;
typedef const FbTk::Button * ConstItem;
@ -58,6 +64,7 @@ public:
int find(ConstItem item);
void setSelected(int index);
void setMaxSizePerClient(unsigned int size);
void setMaxTotalSize(unsigned int size);
void setAlignment(Alignment a);
Item back() { return m_item_list.back(); }
@ -81,6 +88,7 @@ public:
inline const Item& selected() const { return m_selected; }
inline Item selected() { return m_selected; }
unsigned int maxWidthPerClient() const;
unsigned int maxTotalSize() const { return m_max_total_size; }
inline unsigned int maxHeightPerClient() const { return (empty() ? height() : height()/size()); }
inline bool updateLock() const { return m_update_lock; }
@ -97,6 +105,7 @@ private:
Alignment m_align;
unsigned int m_max_size_per_client;
unsigned int m_max_total_size;
ItemList m_item_list;
Item m_selected;
bool m_update_lock;

View file

@ -131,6 +131,26 @@ void XLayer::stackBelowItem(XLayerItem *item, XLayerItem *above) {
}
void XLayer::alignItem(XLayerItem &item) {
// Note: some other things effectively assume that the window list is
// sorted from highest to lowest
size_t winnum = 0,
num = item.numWindows();
Window *winlist = new Window[num];
// fill the rest of the array
XLayerItem::Windows::iterator it = item.getWindows().begin();
XLayerItem::Windows::iterator it_end = item.getWindows().end();
for (; it != it_end; ++it) {
if ((*it)->window()) {
winlist[winnum++] = (*it)->window();
}
}
XRestackWindows(FbTk::App::instance()->display(), winlist, winnum);
delete [] winlist;
}
XLayer::iterator XLayer::insert(XLayerItem &item, unsigned int pos) {
#ifdef DEBUG
// at this point we don't support insertions into a layer other than at the top

View file

@ -48,6 +48,8 @@ public:
void setLayerNum(int layernum) { m_layernum = layernum; };
int getLayerNum() { return m_layernum; };
void restack();
// Put all items on the same layer (called when layer item added to)
void alignItem(XLayerItem &item);
int countWindows();
void stackBelowItem(XLayerItem *item, XLayerItem *above);
XLayerItem *getLowestItem();

View file

@ -81,9 +81,10 @@ void XLayerItem::moveToLayer(int layernum) {
}
void XLayerItem::addWindow(FbWindow &win) {
// I'd like to think we can trust ourselves that it won't be added twice...
// Otherwise we're always scanning through the list.
m_windows.push_back(&win);
// I'd like to think we can trust ourselves that it won't be added twice...
// Otherwise we're always scanning through the list.
m_windows.push_back(&win);
m_layer->alignItem(*this);
}
void XLayerItem::removeWindow(FbWindow &win) {
@ -91,7 +92,8 @@ void XLayerItem::removeWindow(FbWindow &win) {
// Otherwise we're always scanning through the list.
XLayerItem::Windows::iterator it = std::find(m_windows.begin(), m_windows.end(), &win);
m_windows.erase(it);
if (it != m_windows.end())
m_windows.erase(it);
}
void XLayerItem::bringToTop(FbWindow &win) {

View file

@ -25,13 +25,13 @@
#include "FbTk/ImageControl.hh"
#include "FbTk/EventManager.hh"
#include "FbTk/TextButton.hh"
#include "FbTk/App.hh"
#include "FbTk/SimpleCommand.hh"
#include "FbTk/Compose.hh"
#include "FbTk/Transparent.hh"
#include "CompareWindow.hh"
#include "FbWinFrameTheme.hh"
#include "Screen.hh"
#include "Container.hh"
@ -46,24 +46,22 @@
using namespace std;
FbWinFrame::FbWinFrame(FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl,
FbWinFrame::FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl,
FbTk::XLayer &layer,
int x, int y,
unsigned int width, unsigned int height):
m_screen(screen),
m_theme(theme),
m_imagectrl(imgctrl),
m_window(theme.screenNum(), x, y, width, height, ButtonPressMask | ButtonReleaseMask |
ButtonMotionMask | EnterWindowMask, true),
m_layeritem(window(), layer),
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_label(m_titlebar, m_theme.font(), ""),
m_handle(m_window, 0, 0, 100, 5,
ButtonPressMask | ButtonReleaseMask |
ButtonMotionMask | ExposureMask |
@ -82,11 +80,12 @@ FbWinFrame::FbWinFrame(FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl,
EnterWindowMask | LeaveWindowMask),
m_bevel(1),
m_use_titlebar(true),
m_use_tabs(true),
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_tabmode(NOTSET),
m_need_render(true),
m_themelistener(*this),
m_shape(new Shape(m_window, theme.shapePlace())) {
@ -116,8 +115,78 @@ bool FbWinFrame::setOnClickTitlebar(FbTk::RefCount<FbTk::Command> &ref, int mous
return true;
}
bool FbWinFrame::setTabMode(TabMode tabmode) {
if (m_tabmode == tabmode)
return false;
bool ret = true;
// setting tabmode to notset forces it through when
// something is likely to change
if (tabmode == NOTSET)
tabmode = m_tabmode;
// reparent tab container
if (tabmode == EXTERNAL) {
m_tab_container.setBorderWidth(m_window.borderWidth());
m_tab_container.setBorderColor(theme().border().color());
m_tab_container.setEventMask(
ButtonPressMask | ButtonReleaseMask |
ButtonMotionMask | ExposureMask |
EnterWindowMask | LeaveWindowMask);
XGrabButton(m_tab_container.display(), Button1, AnyModifier,
m_tab_container.window(), True, ButtonPressMask,
GrabModeSync, GrabModeSync, None, None);
XUngrabButton(m_tab_container.display(), Button1, Mod1Mask|Mod2Mask|Mod3Mask, m_tab_container.window());
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());
// TODO: tab position
if (m_use_tabs && m_visible)
m_tab_container.show();
else {
ret = false;
m_tab_container.hide();
}
} else {
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.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;
// reconfigure();
}
m_tabmode = tabmode;
return true;
}
void FbWinFrame::hide() {
m_window.hide();
if (m_tabmode == EXTERNAL && m_use_tabs)
m_tab_container.hide();
m_visible = false;
}
@ -130,6 +199,9 @@ void FbWinFrame::show() {
clearAll();
}
if (m_tabmode == EXTERNAL && m_use_tabs)
m_tab_container.show();
m_window.showSubwindows();
m_window.show();
}
@ -214,8 +286,28 @@ void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int heigh
m_window.resize(width, height);
}
if (resize)
if (move)
alignTabs();
if (resize) {
if (m_tabmode == EXTERNAL)
m_tab_container.setMaxTotalSize(width);
reconfigure();
}
}
void FbWinFrame::quietMoveResize(int x, int y,
unsigned int width, unsigned int height) {
m_window.moveResize(x, y, width, height);
if (m_tabmode == EXTERNAL) {
m_tab_container.setMaxTotalSize(width);
alignTabs();
}
}
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());
}
void FbWinFrame::notifyMoved(bool clear) {
@ -224,10 +316,16 @@ void FbWinFrame::notifyMoved(bool clear) {
if (alpha == 255)
return;
if (m_use_titlebar) {
m_titlebar.parentMoved();
//m_label.parentMoved();
if (m_tabmode == EXTERNAL && m_use_tabs || m_use_titlebar) {
m_tab_container.parentMoved();
m_tab_container.for_each(mem_fun(&FbTk::Button::parentMoved));
}
if (m_use_titlebar) {
if (m_tabmode == INTERNAL)
m_label.parentMoved();
m_titlebar.parentMoved();
for_each(m_buttons_left.begin(),
m_buttons_left.end(),
@ -235,7 +333,6 @@ void FbWinFrame::notifyMoved(bool clear) {
for_each(m_buttons_right.begin(),
m_buttons_right.end(),
mem_fun(&FbTk::Button::parentMoved));
m_tab_container.for_each(mem_fun(&FbTk::Button::parentMoved));
}
if (m_use_handle) {
@ -246,7 +343,8 @@ void FbWinFrame::notifyMoved(bool clear) {
if (clear && (m_use_handle || m_use_titlebar)) {
clearAll();
}
} else if (clear && m_tabmode == EXTERNAL && m_use_tabs)
m_tab_container.clear();
}
void FbWinFrame::clearAll() {
@ -260,7 +358,8 @@ void FbWinFrame::clearAll() {
for_each(m_buttons_right.begin(),
m_buttons_right.end(),
mem_fun(&FbTk::Button::clear));
}
} else if (m_tabmode == EXTERNAL && m_use_tabs)
m_tab_container.clear();
if (m_use_handle) {
m_handle.clear();
@ -293,6 +392,7 @@ void FbWinFrame::setFocus(bool newvalue) {
applyTitlebar();
applyHandles();
applyTabContainer();
clearAll();
}
@ -416,6 +516,7 @@ void FbWinFrame::setLabelButtonFocus(FbTk::TextButton &btn) {
applyUnfocusLabel(*m_current_label);
m_current_label = &btn; // current focused button
m_label.setText(btn.text());
if (m_focused)
applyFocusLabel(*m_current_label);
@ -451,11 +552,35 @@ void FbWinFrame::setClientWindow(FbTk::FbWindow &win) {
XChangeWindowAttributes(win.display(), win.window(), CWEventMask|CWDontPropagate, &attrib_set);
m_clientarea.raise();
win.show();
win.raise();
m_window.showSubwindows();
}
bool FbWinFrame::hideTabs() {
if (m_tabmode == INTERNAL || !m_use_tabs) {
m_use_tabs = false;
return false;
}
m_use_tabs = false;
m_tab_container.hide();
return true;
}
bool FbWinFrame::showTabs() {
if (m_tabmode == INTERNAL || m_use_tabs) {
m_use_tabs = true;
return false; // nothing changed
}
m_use_tabs = true;
if (m_visible)
m_tab_container.show();
return true;
}
bool FbWinFrame::hideTitlebar() {
if (!m_use_titlebar)
return false;
@ -484,6 +609,7 @@ bool FbWinFrame::showTitlebar() {
// only add one borderwidth (as the other border is still the "top" border)
m_window.resize(m_window.width(), m_window.height() + m_titlebar.height() +
m_titlebar.borderWidth());
return true;
}
@ -555,6 +681,7 @@ void FbWinFrame::setEventHandler(FbTk::EventHandler &evh) {
FbTk::EventManager &evm = *FbTk::EventManager::instance();
evm.add(evh, m_tab_container);
evm.add(evh, m_label);
evm.add(evh, m_titlebar);
evm.add(evh, m_handle);
evm.add(evh, m_grip_right);
@ -569,6 +696,7 @@ void FbWinFrame::setEventHandler(FbTk::EventHandler &evh) {
void FbWinFrame::removeEventHandler() {
FbTk::EventManager &evm = *FbTk::EventManager::instance();
evm.remove(m_tab_container);
evm.remove(m_label);
evm.remove(m_titlebar);
evm.remove(m_handle);
evm.remove(m_grip_right);
@ -579,6 +707,9 @@ void FbWinFrame::removeEventHandler() {
void FbWinFrame::buttonPressEvent(XButtonEvent &event) {
// we can ignore which window the event was generated for
if (event.window == m_label.window() && m_current_label)
event.window = m_current_label->window();
m_tab_container.tryButtonPressEvent(event);
if (event.window == m_grip_right.window() ||
event.window == m_grip_left.window() ||
@ -595,6 +726,8 @@ void FbWinFrame::buttonPressEvent(XButtonEvent &event) {
void FbWinFrame::buttonReleaseEvent(XButtonEvent &event) {
// we can ignore which window the event was generated for
if (event.window == m_label.window() && m_current_label)
event.window = m_current_label->window();
// we continue even if a button got the event
m_tab_container.tryButtonReleaseEvent(event);
@ -626,6 +759,8 @@ void FbWinFrame::exposeEvent(XExposeEvent &event) {
m_titlebar.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_label == event.window) {
m_label.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) {
@ -696,6 +831,8 @@ void FbWinFrame::reconfigure() {
} else
m_titlebar.lower();
if (m_tabmode == EXTERNAL)
m_tab_container.resize(m_tab_container.width(), buttonHeight());
// leave client+grips alone if we're shaded (it'll get fixed when we unshade)
if (!m_shaded) {
@ -788,7 +925,7 @@ void FbWinFrame::redrawTitlebar() {
if (isVisible()) {
m_tab_container.clear();
//m_label.clear();
m_label.clear();
m_titlebar.clear();
}
}
@ -825,16 +962,23 @@ void FbWinFrame::reconfigureTitlebar() {
next_x += m_bevel;
// space left on titlebar between left and right buttons
unsigned int space_left = m_titlebar.width() - next_x;
int space_left = m_titlebar.width() - next_x;
if (!m_buttons_right.empty())
space_left -= m_buttons_right.size() * (button_size + m_bevel);
space_left -= m_bevel;
m_tab_container.moveResize(next_x, m_bevel,
space_left, button_size);
next_x += m_tab_container.width() + m_bevel;;
if (space_left <= 0)
space_left = 1;
m_label.moveResize(next_x, m_bevel, space_left, button_size);
if (m_tabmode == INTERNAL)
m_tab_container.moveResize(next_x, m_bevel,
space_left, button_size);
next_x += m_label.width() + m_bevel;
// finaly set new buttons to the right
for (size_t i=0; i < m_buttons_right.size();
@ -851,13 +995,13 @@ void FbWinFrame::renderAll() {
renderTitlebar();
renderHandles();
renderLabelButtons();
renderTabContainer();
}
void FbWinFrame::applyAll() {
applyTitlebar();
applyHandles();
applyLabelButtons();
applyTabContainer();
}
void FbWinFrame::renderTitlebar() {
@ -878,18 +1022,47 @@ void FbWinFrame::renderTitlebar() {
m_title_unfocused_pm,
m_titlebar.width(), m_titlebar.height());
//!! TODO: don't render label if internal tabs
render(m_theme.labelFocusTexture(), m_label_focused_color,
m_label_focused_pm,
m_tab_container.width(), m_tab_container.height());
m_label.width(), m_label.height());
render(m_theme.labelUnfocusTexture(), m_label_unfocused_color,
m_label_unfocused_pm,
m_tab_container.width(), m_tab_container.height());
m_label.width(), m_label.height());
renderButtons();
}
void FbWinFrame::renderTabContainer() {
if (!isVisible()) {
m_need_render = true;
return;
}
render(m_theme.labelFocusTexture(), m_tabcontainer_focused_color,
m_tabcontainer_focused_pm,
m_tab_container.width(), m_tab_container.height());
render(m_theme.labelUnfocusTexture(), m_tabcontainer_unfocused_color,
m_tabcontainer_unfocused_pm,
m_tab_container.width(), m_tab_container.height());
render(m_theme.labelFocusTexture(), m_labelbutton_focused_color,
m_labelbutton_focused_pm,
m_tab_container.width(), m_tab_container.height());
render(m_theme.labelUnfocusTexture(), m_labelbutton_unfocused_color,
m_labelbutton_unfocused_pm,
m_tab_container.width(), m_tab_container.height());
render(m_theme.labelActiveTexture(), m_labelbutton_active_color,
m_labelbutton_active_pm,
m_tab_container.width(), m_tab_container.height());
}
void FbWinFrame::applyTitlebar() {
// set up pixmaps for titlebar windows
@ -902,13 +1075,13 @@ void FbWinFrame::applyTitlebar() {
unsigned char alpha = (m_focused?theme().focusedAlpha():theme().unfocusedAlpha());
m_titlebar.setAlpha(alpha);
m_tab_container.setAlpha(alpha);
m_label.setAlpha(alpha);
if (label_pm != 0)
m_tab_container.setBackgroundPixmap(label_pm);
else
m_tab_container.setBackgroundColor(label_color);
m_label.setBackgroundPixmap(label_pm);
else
m_label.setBackgroundColor(label_color);
if (title_pm != 0)
m_titlebar.setBackgroundPixmap(title_pm);
else
@ -1036,6 +1209,7 @@ void FbWinFrame::init() {
// clear pixmaps
m_title_focused_pm = m_title_unfocused_pm = 0;
m_label_focused_pm = m_label_unfocused_pm = 0;
m_tabcontainer_focused_pm = m_tabcontainer_unfocused_pm = 0;
m_labelbutton_focused_pm = m_labelbutton_unfocused_pm = m_labelbutton_active_pm = 0;
m_handle_focused_pm = m_handle_unfocused_pm = 0;
m_button_pm = m_button_unfocused_pm = m_button_pressed_pm = 0;
@ -1045,8 +1219,20 @@ void FbWinFrame::init() {
m_button_size = 26;
m_clientarea.setBorderWidth(0);
m_label.setBorderWidth(0);
m_shaded = false;
// TODO: configurable default (on compile, for backwards compat)
// setTabMode(EXTERNAL);
setTabMode(INTERNAL);
m_label.setEventMask(ExposureMask | ButtonPressMask |
ButtonReleaseMask | ButtonMotionMask |
EnterWindowMask);
m_label.show();
m_tab_container.show();
m_tab_container.raise();
showHandle();
showTitlebar();
@ -1104,62 +1290,52 @@ void FbWinFrame::render(const FbTk::Texture &tex, FbTk::Color &col, Pixmap &pm,
void FbWinFrame::getCurrentFocusPixmap(Pixmap &label_pm, Pixmap &title_pm,
FbTk::Color &label_color, FbTk::Color &title_color) {
if (m_focused) {
if (m_labelbutton_focused_pm != 0)
label_pm = m_labelbutton_focused_pm;
if (m_label_focused_pm != 0)
label_pm = m_label_focused_pm;
else
label_color = m_labelbutton_focused_color;
label_color = m_label_focused_color;
if (m_title_focused_pm != 0)
title_pm = m_title_focused_pm;
else
title_color = m_title_focused_color;
} else {
getActiveLabelPixmap(label_pm, title_pm,
label_color, title_color);
if (m_label_unfocused_pm != 0)
label_pm = m_label_unfocused_pm;
else
label_color = m_label_unfocused_color;
if (m_title_unfocused_pm != 0)
title_pm = m_title_unfocused_pm;
else
title_color = m_title_unfocused_color;
}
}
void FbWinFrame::applyTabContainer() {
m_tab_container.setAlpha(m_focused?theme().focusedAlpha():theme().unfocusedAlpha());
// do the parent container
Pixmap tabcontainer_pm = None;
FbTk::Color *tabcontainer_color = NULL;
if (m_focused) {
if (m_tabcontainer_focused_pm != 0)
tabcontainer_pm = m_tabcontainer_focused_pm;
else
tabcontainer_color = &m_tabcontainer_focused_color;
} else {
if (m_tabcontainer_unfocused_pm != 0)
tabcontainer_pm = m_tabcontainer_unfocused_pm;
else
tabcontainer_color = &m_tabcontainer_unfocused_color;
}
}
// only called if not focused
void FbWinFrame::getActiveLabelPixmap(Pixmap &label_pm, Pixmap &title_pm,
FbTk::Color &label_color,
FbTk::Color &title_color) {
if (m_labelbutton_active_pm != 0)
label_pm = m_labelbutton_active_pm;
if (tabcontainer_pm != 0)
m_tab_container.setBackgroundPixmap(tabcontainer_pm);
else
label_color = m_labelbutton_active_color;
if (m_title_unfocused_pm != 0)
title_pm = m_title_unfocused_pm;
else
title_color = m_title_unfocused_color;
}
void FbWinFrame::renderLabelButtons() {
if (!isVisible()) {
m_need_render = true;
return;
}
render(m_theme.labelFocusTexture(), m_labelbutton_focused_color,
m_labelbutton_focused_pm,
m_tab_container.width(), m_tab_container.height());
render(m_theme.labelUnfocusTexture(), m_labelbutton_unfocused_color,
m_labelbutton_unfocused_pm,
m_tab_container.width(), m_tab_container.height());
render(m_theme.labelActiveTexture(), m_labelbutton_active_color,
m_labelbutton_active_pm,
m_tab_container.width(), m_tab_container.height());
}
void FbWinFrame::applyLabelButtons() {
m_tab_container.setBackgroundColor(*tabcontainer_color);
// and the labelbuttons in it
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) {
@ -1186,6 +1362,8 @@ void FbWinFrame::setBorderWidth(unsigned int border_width) {
window().setBorderWidth(border_width);
window().setBorderColor(theme().border().color());
setTabMode(NOTSET);
titlebar().setBorderWidth(border_width);
titlebar().setBorderColor(theme().border().color());
@ -1200,13 +1378,16 @@ void FbWinFrame::setBorderWidth(unsigned int border_width) {
if (bw_changes != 0)
resize(width(), height() + bw_changes);
if (m_tabmode == EXTERNAL)
alignTabs();
}
void FbWinFrame::applyFocusLabel(FbTk::TextButton &button) {
button.setBorderWidth(1);
button.setGC(theme().labelTextFocusGC());
button.setJustify(theme().justify());
button.setBorderWidth(1);
button.setAlpha(m_focused?theme().focusedAlpha():theme().unfocusedAlpha());
if (m_labelbutton_focused_pm != 0) {
@ -1217,10 +1398,9 @@ void FbWinFrame::applyFocusLabel(FbTk::TextButton &button) {
}
void FbWinFrame::applyActiveLabel(FbTk::TextButton &button) {
button.setBorderWidth(1);
button.setGC(theme().labelTextActiveGC());
button.setJustify(theme().justify());
button.setBorderWidth(1);
button.setAlpha(m_focused?theme().focusedAlpha():theme().unfocusedAlpha());
if (m_labelbutton_active_pm != 0) {
@ -1362,3 +1542,18 @@ void FbWinFrame::gravityTranslate(int &x, int &y, unsigned int width, unsigned i
move(x, y);
}
}
int FbWinFrame::heightOffset() const {
if (m_tabmode == EXTERNAL && m_use_tabs)
return m_tab_container.height() + m_window.borderWidth();
else
return 0;
}
int FbWinFrame::yOffset() const {
if (m_tabmode == EXTERNAL && m_use_tabs)
return m_tab_container.height() + m_window.borderWidth();
else
return 0;
}

View file

@ -30,6 +30,8 @@
#include "FbTk/Observer.hh"
#include "FbTk/Color.hh"
#include "FbTk/FbPixmap.hh"
#include "FbTk/XLayerItem.hh"
#include "FbTk/TextButton.hh"
#include "Container.hh"
#include <vector>
@ -39,6 +41,7 @@
class Shape;
class FbWinFrameTheme;
class BScreen;
namespace FbTk {
class TextButton;
@ -46,27 +49,30 @@ class ImageControl;
class Command;
class Button;
class Texture;
class XLayer;
}
/// 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 };
// STRICTINTERNAL means it doesn't go external automatically when no titlebar
enum TabMode { NOTSET = 0, INTERNAL = 1, EXTERNAL };
typedef FbTk::TextButton *ButtonId; ///< defines a button id
/// create a top level window
FbWinFrame(FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl,
FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl,
FbTk::XLayer &layer,
int x, int y,
unsigned int width, unsigned int height);
/// create a frame window inside another FbWindow, NOT IMPLEMENTED!
FbWinFrame(FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl,
/* /// create a frame window inside another FbWindow, NOT IMPLEMENTED!
FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl,
const FbTk::FbWindow &parent,
int x, int y,
unsigned int width, unsigned int height);
*/
/// destroy frame
~FbWinFrame();
@ -94,6 +100,10 @@ public:
unsigned int width, unsigned int height,
bool move = true, bool resize = true, int win_gravity=ForgetGravity);
// move without transparency or special effects (generally when dragging)
void quietMoveResize(int x, int y,
unsigned int width, unsigned int height);
/// some outside move/resize happened, and we need to notify all of our windows
/// in case of transparency
void notifyMoved(bool clear);
@ -101,7 +111,9 @@ public:
/// set focus/unfocus style
void setFocus(bool newvalue);
inline void setFocusTitle(const std::string &str) { m_label.setText(str); }
void setDoubleClickTime(unsigned int time);
bool setTabMode(TabMode tabmode);
/// add a button to the left of the label
void addLeftButton(FbTk::Button *btn);
@ -138,6 +150,8 @@ public:
// these return true/false for if something changed
bool hideTitlebar();
bool showTitlebar();
bool hideTabs();
bool showTabs();
bool hideHandle();
bool showHandle();
bool hideAllDecorations();
@ -172,6 +186,13 @@ public:
inline int y() const { return m_window.y(); }
inline unsigned int width() const { return m_window.width(); }
inline unsigned int height() const { return m_window.height(); }
// extra bits for tabs
inline int xOffset() const { return 0; }
int yOffset() const;
inline int widthOffset() const { return 0; }
int heightOffset() const;
inline const FbTk::FbWindow &window() const { return m_window; }
inline FbTk::FbWindow &window() { return m_window; }
/// @return titlebar window
@ -201,6 +222,10 @@ public:
unsigned int titlebarHeight() const { return m_titlebar.height(); }
/// @return size of button
unsigned int buttonHeight() const;
bool externalTabMode() const { return m_tabmode == EXTERNAL; }
inline const FbTk::XLayerItem &layerItem() const { return m_layeritem; }
inline FbTk::XLayerItem &layerItem() { return m_layeritem; }
//@}
@ -216,7 +241,7 @@ private:
void renderAll();
void renderTitlebar();
void renderHandles();
void renderLabelButtons();
void renderTabContainer(); // and labelbuttons
void renderButtons(); // subset of renderTitlebar - don't call directly
@ -233,7 +258,7 @@ private:
void applyAll();
void applyTitlebar();
void applyHandles();
void applyLabelButtons();
void applyTabContainer(); // and label buttons
void applyFocusLabel(FbTk::TextButton &button);
void applyUnfocusLabel(FbTk::TextButton &button);
void applyActiveLabel(FbTk::TextButton &button);
@ -246,11 +271,15 @@ private:
/// initiate inserted button for current theme
void applyButton(FbTk::Button &btn);
void alignTabs();
//@}
/// initiate some commont variables
void init();
BScreen &m_screen;
FbWinFrameTheme &m_theme; ///< theme to be used
FbTk::ImageControl &m_imagectrl; ///< Image control for rendering
/**
@ -258,9 +287,12 @@ private:
*/
//@{
FbTk::FbWindow m_window; ///< base window that holds each decorations (ie titlebar, handles)
// want this deleted before the windows in it
FbTk::XLayerItem m_layeritem;
FbTk::FbWindow m_titlebar; ///< titlebar window
Container m_tab_container; ///< Holds tabs
FbTk::FbWindow m_label; ///< holds title
FbTk::TextButton m_label; ///< holds title
FbTk::FbWindow m_handle; ///< handle between grips
FbTk::FbWindow m_grip_right, ///< rightgrip
m_grip_left; ///< left grip
@ -274,6 +306,7 @@ private:
std::string m_titletext; ///< text to be displayed int m_label
int m_bevel; ///< bevel between titlebar items and titlebar
bool m_use_titlebar; ///< if we should use titlebar
bool m_use_tabs; ///< if we should use tabs (turns them off in external mode only)
bool m_use_handle; ///< if we should use handle
bool m_focused; ///< focused/unfocused mode
bool m_visible; ///< if we are currently showing
@ -285,17 +318,22 @@ private:
Pixmap m_title_focused_pm; ///< pixmap for focused title
FbTk::Color m_title_focused_color; ///< color for focused title
Pixmap m_title_unfocused_pm; ///< pixmap for unfocused title
FbTk::Color m_title_unfocused_color; ///< color for unfocued title
FbTk::Color m_title_unfocused_color; ///< color for unfocused title
Pixmap m_label_focused_pm; ///< pixmap for focused label
Pixmap m_label_focused_pm; ///< pixmap for focused label (only visible with external tabs)
FbTk::Color m_label_focused_color; ///< color for focused label
Pixmap m_label_unfocused_pm; ///< pixmap for unfocused label
FbTk::Color m_label_unfocused_color; ///< color for unfocued label
FbTk::Color m_label_unfocused_color; ///< color for unfocused label
Pixmap m_tabcontainer_focused_pm; ///< pixmap for focused tab container
FbTk::Color m_tabcontainer_focused_color; ///< color for focused tab container
Pixmap m_tabcontainer_unfocused_pm; ///< pixmap for unfocused tab container
FbTk::Color m_tabcontainer_unfocused_color; ///< color for unfocused tab container
Pixmap m_labelbutton_focused_pm; ///< pixmap for focused label
FbTk::Color m_labelbutton_focused_color; ///< color for focused label
Pixmap m_labelbutton_unfocused_pm; ///< pixmap for unfocused label
FbTk::Color m_labelbutton_unfocused_color; ///< color for unfocued label
FbTk::Color m_labelbutton_unfocused_color; ///< color for unfocused label
Pixmap m_labelbutton_active_pm; ///< pixmap for active label
FbTk::Color m_labelbutton_active_color; ///< color for active label

View file

@ -416,6 +416,7 @@ int Remember::parseApp(ifstream &file, Application &app, string *first_line) {
FluxboxWindow::DECORM_TITLEBAR
| FluxboxWindow::DECORM_ICONIFY
| FluxboxWindow::DECORM_MENU
| FluxboxWindow::DECORM_TAB
);
} else if (str_label == "TOOL") {
app.rememberDecostate((unsigned int)
@ -427,6 +428,12 @@ int Remember::parseApp(ifstream &file, Application &app, string *first_line) {
FluxboxWindow::DECORM_BORDER
| FluxboxWindow::DECORM_MENU
);
} else if (str_label == "TAB") {
app.rememberDecostate((unsigned int)
FluxboxWindow::DECORM_BORDER
| FluxboxWindow::DECORM_MENU
| FluxboxWindow::DECORM_TAB
);
} else {
unsigned int mask;
const char * str = str_label.c_str();

View file

@ -57,11 +57,12 @@ bool RowSmartPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowli
if (screen_placement.rowDirection() == ScreenPlacement::RIGHTLEFT)
change_x = -1;
int win_w = win.width() + win.fbWindow().borderWidth()*2 + win.widthOffset();
int win_h = win.height() + win.fbWindow().borderWidth()*2 + win.heightOffset();
int x_off = win.xOffset();
int y_off = win.yOffset();
int win_h = win.height() + win.fbWindow().borderWidth()*2;
int win_w = win.width() + win.fbWindow().borderWidth()*2;
int test_y;
if (top_bot)
test_y = head_top;
@ -102,10 +103,10 @@ bool RowSmartPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowli
for (; win_it != win_it_end && placed; ++win_it) {
FluxboxWindow &window = **win_it;
int curr_x = window.x();
int curr_y = window.y();
int curr_w = window.width() + window.fbWindow().borderWidth()*2;
int curr_h = window.height() + window.fbWindow().borderWidth()*2;
int curr_x = window.x() + window.xOffset();
int curr_y = window.y() + window.yOffset();
int curr_w = window.width() + window.fbWindow().borderWidth()*2 + window.widthOffset();
int curr_h = window.height() + window.fbWindow().borderWidth()*2 + window.heightOffset();
if (curr_x < test_x + win_w &&
curr_x + curr_w > test_x &&
@ -138,8 +139,8 @@ bool RowSmartPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowli
if (placed) {
place_x = test_x;
place_y = test_y;
place_x = test_x + x_off;
place_y = test_y + y_off;
break;
}

View file

@ -201,7 +201,8 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
scrname+".overlay.capStyle",
altscrname+".overlay.CapStyle"),
scroll_action(rm, "", scrname+".windowScrollAction", altscrname+".WindowScrollAction"),
scroll_reverse(rm, false, scrname+".windowScrollReverse", altscrname+".WindowScrollReverse") {
scroll_reverse(rm, false, scrname+".windowScrollReverse", altscrname+".WindowScrollReverse"),
default_external_tabs(rm, false /* TODO: autoconf option? */ , scrname+".externalTabs", altscrname+".ExternalTabs") {
}
@ -1549,6 +1550,9 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
_BOOLITEM(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,
"Click Raises", "Click Raises",
*resource.click_raises, saverc_cmd);

View file

@ -138,6 +138,7 @@ public:
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 Slit *slit() { return m_slit.get(); }
inline const Slit *slit() const { return m_slit.get(); }
@ -446,6 +447,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;
} resource;

View file

@ -113,15 +113,14 @@ bool ScreenPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowlist
int win_w = win.width() + win.fbWindow().borderWidth()*2,
win_h = win.height() + win.fbWindow().borderWidth()*2;
int win_w = win.width() + win.fbWindow().borderWidth()*2 + win.widthOffset(),
win_h = win.height() + win.fbWindow().borderWidth()*2 + win.heightOffset();
// make sure the window is inside our screen(head) area
if (place_x + win_w > head_right)
place_x = (head_right - win_w) / 2;
place_x = (head_right - win_w) / 2 + win.xOffset();
if (place_y + win_h > head_bot)
place_y = (head_bot - win_h) / 2;
place_y = (head_bot - win_h) / 2 + win.yOffset();
return true;
}

View file

@ -43,6 +43,7 @@ bool UnderMousePlacement::placeWindow(const std::vector<FluxboxWindow *> &list,
&ignore_i, &ignore_i, &ignore_ui);
// 2*border = border on each side of the screen
// not using offset ones because we won't let tabs influence the "centre"
int win_w = win.width() + win.fbWindow().borderWidth()*2,
win_h = win.height() + win.fbWindow().borderWidth()*2;

View file

@ -298,7 +298,7 @@ void WinButton::drawType() {
if (m_icon_mask.drawable())
XSetClipMask(m_listen_to.fbWindow().display(), gc(), None);
} else {
for (int y = height()/3; y <= height() - height()/3; y+=3) {
for (unsigned int y = height()/3; y <= height() - height()/3; y+=3) {
drawLine(gc(), width()/4, y, width() - width()/4 - oddW - 1, y);
}
drawRectangle(gc(),

View file

@ -311,8 +311,7 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbWinFrameTheme &tm,
m_old_pos_x(0), m_old_pos_y(0),
m_old_width(1), m_old_height(1),
m_last_button_x(0), m_last_button_y(0),
m_frame(tm, client.screen().imageControl(), 0, 0, 100, 100),
m_layeritem(m_frame.window(), layer),
m_frame(client.screen(), tm, client.screen().imageControl(), layer, 0, 0, 100, 100),
m_layernum(layer.getLayerNum()),
m_old_layernum(0),
m_parent(client.screen().rootWindow()),
@ -344,6 +343,7 @@ FluxboxWindow::~FluxboxWindow() {
// no longer a valid window to do stuff with
Fluxbox::instance()->removeWindowSearchGroup(frame().window().window());
Fluxbox::instance()->removeWindowSearchGroup(frame().tabcontainer().window());
Client2ButtonMap::iterator it = m_labelbuttons.begin();
Client2ButtonMap::iterator it_end = m_labelbuttons.end();
@ -394,6 +394,12 @@ void FluxboxWindow::init() {
frame().setUseShape(!m_shaped);
if (screen().getDefaultExternalTabs()) {
frame().setTabMode(FbWinFrame::EXTERNAL);
} else {
frame().setTabMode(FbWinFrame::INTERNAL);
}
//!! TODO init of client should be better
// we don't want to duplicate code here and in attachClient
m_clientlist.push_back(m_client);
@ -467,6 +473,7 @@ void FluxboxWindow::init() {
m_timer.fireOnce(true);
Fluxbox::instance()->saveWindowSearchGroup(frame().window().window(), this);
Fluxbox::instance()->saveWindowSearchGroup(frame().tabcontainer().window(), this);
/**************************************************/
/* Read state above here, apply state below here. */
@ -1146,8 +1153,11 @@ void FluxboxWindow::updateTitleFromClient(WinClient &client) {
client.updateTitle();
// compare old title with new and see if we need to update
// graphics
if (m_labelbuttons[&client]->text() != client.title())
if (m_labelbuttons[&client]->text() != client.title()) {
m_labelbuttons[&client]->setText(client.title());
if (&client == m_client)
frame().setFocusTitle(client.title());
}
}
/// update icon title from client
@ -2648,7 +2658,7 @@ void FluxboxWindow::buttonPressEvent(XButtonEvent &be) {
setInputFocus();
}
if (frame().window().window() == be.window) {
if (frame().window().window() == be.window || frame().tabcontainer().window() == be.window) {
if (screen().clickRaises())
raise();
#ifdef DEBUG
@ -2694,17 +2704,28 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
if (isMoving() && me.window == parent()) {
me.window = frame().window().window();
}
bool inside_titlebar = (frame().titlebar() == me.window || frame().label() == me.window ||
frame().handle() == me.window || frame().window() == me.window);
bool inside_titlebar = (frame().titlebar() == me.window
|| frame().label() == me.window
|| frame().tabcontainer() == me.window
|| frame().handle() == me.window
|| frame().window() == me.window);
if (Fluxbox::instance()->getIgnoreBorder()
&& !(me.state & Mod1Mask) // really should check for exact matches
&& !(isMoving() || isResizing() || m_attaching_tab != 0)) {
int borderw = frame().window().borderWidth();
if (me.x_root < (frame().x() + borderw) ||
//!! TODO(tabs): the below test ought to be in FbWinFrame
if ((me.x_root < (frame().x() + borderw) ||
me.y_root < (frame().y() + borderw) ||
me.x_root > (frame().x() + (int)frame().width() + borderw) ||
me.y_root > (frame().y() + (int)frame().height() + borderw))
me.y_root > (frame().y() + (int)frame().height() + borderw)) &&
( !frame().externalTabMode() ||
(me.x_root < (frame().tabcontainer().x() + borderw) ||
me.y_root < (frame().tabcontainer().y() + borderw) ||
me.x_root > (frame().tabcontainer().x() + (int)frame().tabcontainer().width() + borderw) ||
me.y_root > (frame().tabcontainer().y() + (int)frame().tabcontainer().height() + borderw)
)))
return;
}
@ -2794,7 +2815,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
} else {
//moveResize(dx, dy, frame().width(), frame().height());
// need to move the base window without interfering with transparency
frame().window().moveResize(dx, dy, frame().width(), frame().height());
frame().quietMoveResize(dx, dy, frame().width(), frame().height());
}
screen().showPosition(dx, dy);
@ -3077,11 +3098,26 @@ void FluxboxWindow::applyDecorations(bool initial) {
frame().setBorderWidth(border_width);
}
// we rely on frame not doing anything if it is already shown/hidden
if (decorations.titlebar)
client_move |= frame().showTitlebar();
// tab deocration only affects if we're external
// must do before the setTabMode in case it goes
// to external and is meant to be hidden
if (decorations.tab)
client_move |= frame().showTabs();
else
client_move |= frame().hideTabs();
// we rely on frame not doing anything if it is already shown/hidden
if (decorations.titlebar) {
bool change = frame().showTitlebar();
client_move |= change;
if (change && !screen().getDefaultExternalTabs()) {
client_move |= frame().setTabMode(FbWinFrame::INTERNAL);
}
} else {
client_move |= frame().hideTitlebar();
if (decorations.tab)
client_move |= frame().setTabMode(FbWinFrame::EXTERNAL);
}
if (decorations.handle) {
client_move |= frame().showHandle();
@ -4048,6 +4084,7 @@ void FluxboxWindow::associateClient(WinClient &client) {
Fluxbox::instance()->getTabsPadding());
m_labelbuttons[&client] = btn;
FbTk::EventManager &evm = *FbTk::EventManager::instance();

View file

@ -316,8 +316,8 @@ public:
inline const BScreen &screen() const { return m_screen; }
inline BScreen &screen() { return m_screen; }
inline const FbTk::XLayerItem &layerItem() const { return m_layeritem; }
inline FbTk::XLayerItem &layerItem() { return m_layeritem; }
inline const FbTk::XLayerItem &layerItem() const { return m_frame.layerItem(); }
inline FbTk::XLayerItem &layerItem() { return m_frame.layerItem(); }
Window clientWindow() const;
@ -337,6 +337,11 @@ public:
inline unsigned int width() const { return frame().width(); }
inline unsigned int height() const { return frame().height(); }
inline int xOffset() const { return frame().xOffset(); }
inline int yOffset() const { return frame().yOffset(); }
inline int widthOffset() const { return frame().widthOffset(); }
inline int heightOffset() const { return frame().heightOffset(); }
unsigned int workspaceNumber() const { return m_workspace_number; }
int layerNum() const { return m_layernum; }
@ -504,7 +509,6 @@ private:
m_last_button_y; ///< last known y position of the mouse button
FbWinFrame m_frame;
FbTk::XLayerItem m_layeritem;
int m_layernum;
int m_old_layernum;

View file

@ -175,6 +175,8 @@ int handleXErrors(Display *d, XErrorEvent *e) {
XGetErrorText(d, e->error_code, errtxt, 128);
cerr<<"Fluxbox: X Error: "<<errtxt<<"("<<(int)e->error_code<<") opcodes "<<
(int)e->request_code<<"/"<<(int)e->minor_code<<" resource 0x"<<hex<<(int)e->resourceid<<dec<<endl;
// if (e->error_code != 9 && e->error_code != 183)
// kill(0, 2);
}
#endif // !DEBUG
@ -193,15 +195,15 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
// TODO: shouldn't need a separate one for screen
m_screen_rm(m_resourcemanager),
m_rc_tabs(m_resourcemanager, true, "session.tabs", "Session.Tabs"),
m_rc_tabs_padding(m_resourcemanager, 0, "session.tabPadding", "Session.TabPadding"),
m_rc_focused_tab_min_width(m_resourcemanager, 0, "session.focusTabMinWidth",
"Session.FocusTabMinWidth"),
m_rc_ignoreborder(m_resourcemanager, false, "session.ignoreBorder", "Session.IgnoreBorder"),
m_rc_pseudotrans(m_resourcemanager, false, "session.forcePseudoTransparency", "Session.forcePseudoTransparency"),
m_rc_colors_per_channel(m_resourcemanager, 4,
"session.colorsPerChannel", "Session.ColorsPerChannel"),
m_rc_numlayers(m_resourcemanager, 13, "session.numLayers", "Session.NumLayers"),
m_rc_double_click_interval(m_resourcemanager, 250, "session.doubleClickInterval", "Session.DoubleClickInterval"),
m_rc_tabs_padding(m_resourcemanager, 0, "session.tabPadding", "Session.TabPadding"),
m_rc_focused_tab_min_width(m_resourcemanager, 0, "session.focusTabMinWidth",
"Session.FocusTabMinWidth"),
m_rc_stylefile(m_resourcemanager, DEFAULTSTYLE, "session.styleFile", "Session.StyleFile"),
m_rc_styleoverlayfile(m_resourcemanager, "~/.fluxbox/overlay", "session.styleOverlay", "Session.StyleOverlay"),
m_rc_menufile(m_resourcemanager, DEFAULTMENU, "session.menuFile", "Session.MenuFile"),
@ -358,8 +360,8 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
}
// init all "screens"
for(i = 0; i < screens.size(); i++)
initScreen(screens[i]);
for(unsigned int s = 0; s < screens.size(); s++)
initScreen(screens[s]);
XAllowEvents(disp, ReplayPointer, CurrentTime);