move FbWinFrame::State class to a new file
This commit is contained in:
parent
08c8c6431f
commit
55fd49614b
10 changed files with 486 additions and 459 deletions
|
@ -503,7 +503,7 @@ void SetTitleCmd::real_execute() {
|
|||
REGISTER_COMMAND_WITH_ARGS(setdecor, SetDecorCmd, void);
|
||||
|
||||
SetDecorCmd::SetDecorCmd(const std::string &args):
|
||||
m_mask(FbWinFrame::getDecoMaskFromString(args)) { }
|
||||
m_mask(WindowState::getDecoMaskFromString(args)) { }
|
||||
|
||||
void SetDecorCmd::real_execute() {
|
||||
fbwindow().setDecorationMask(m_mask);
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "FbTk/Compose.hh"
|
||||
#include "FbTk/Transparent.hh"
|
||||
#include "FbTk/CompareEqual.hh"
|
||||
#include "FbTk/StringUtil.hh"
|
||||
#include "FbTk/TextUtils.hh"
|
||||
|
||||
#include "FbWinFrameTheme.hh"
|
||||
|
@ -194,7 +193,7 @@ void FbWinFrame::show() {
|
|||
Toggle shade state, and resize window
|
||||
*/
|
||||
void FbWinFrame::shade() {
|
||||
if (!(m_state.deco_mask & DECORM_TITLEBAR))
|
||||
if (!(m_state.deco_mask & WindowState::DECORM_TITLEBAR))
|
||||
return;
|
||||
|
||||
// toggle shade
|
||||
|
@ -254,7 +253,8 @@ void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int heigh
|
|||
m_window.resize(width, height);
|
||||
}
|
||||
|
||||
saveGeometry();
|
||||
m_state.saveGeometry(window().x(), window().y(),
|
||||
window().width(), window().height());
|
||||
|
||||
if (move || (resize && m_screen.getTabPlacement() != TOPLEFT &&
|
||||
m_screen.getTabPlacement() != LEFTTOP))
|
||||
|
@ -283,7 +283,8 @@ void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int heigh
|
|||
void FbWinFrame::quietMoveResize(int x, int y,
|
||||
unsigned int width, unsigned int height) {
|
||||
m_window.moveResize(x, y, width, height);
|
||||
saveGeometry();
|
||||
m_state.saveGeometry(window().x(), window().y(),
|
||||
window().width(), window().height());
|
||||
if (m_tabmode == EXTERNAL) {
|
||||
|
||||
switch(m_screen.getTabPlacement()) {
|
||||
|
@ -534,21 +535,6 @@ void FbWinFrame::setMaximized(int value) {
|
|||
applyState();
|
||||
}
|
||||
|
||||
void FbWinFrame::saveGeometry() {
|
||||
if (m_state.fullscreen || m_state.maximized == MAX_FULL)
|
||||
return;
|
||||
|
||||
if (!(m_state.maximized & MAX_HORZ)) {
|
||||
m_state.x = x();
|
||||
m_state.width = width();
|
||||
}
|
||||
if (!(m_state.maximized & MAX_VERT)) {
|
||||
m_state.y = y();
|
||||
if (!m_state.shaded)
|
||||
m_state.height = height();
|
||||
}
|
||||
}
|
||||
|
||||
void FbWinFrame::applyState() {
|
||||
applyDecorations();
|
||||
|
||||
|
@ -556,7 +542,7 @@ void FbWinFrame::applyState() {
|
|||
int new_x = m_state.x, new_y = m_state.y;
|
||||
unsigned int new_w = m_state.width, new_h = m_state.height;
|
||||
|
||||
if (m_state.maximized & MAX_VERT) {
|
||||
if (m_state.maximized & WindowState::MAX_VERT) {
|
||||
new_y = m_screen.maxTop(head);
|
||||
new_h = m_screen.maxBottom(head) - new_y - 2*window().borderWidth();
|
||||
if (!m_screen.getMaxOverTabs()) {
|
||||
|
@ -564,7 +550,7 @@ void FbWinFrame::applyState() {
|
|||
new_h -= heightOffset();
|
||||
}
|
||||
}
|
||||
if (m_state.maximized & MAX_HORZ) {
|
||||
if (m_state.maximized & WindowState::MAX_HORZ) {
|
||||
new_x = m_screen.maxLeft(head);
|
||||
new_w = m_screen.maxRight(head) - new_x - 2*window().borderWidth();
|
||||
if (!m_screen.getMaxOverTabs()) {
|
||||
|
@ -1482,50 +1468,11 @@ void FbWinFrame::applyTabContainer() {
|
|||
}
|
||||
}
|
||||
|
||||
int FbWinFrame::getDecoMaskFromString(const string &str_label) {
|
||||
string label = FbTk::StringUtil::toLower(str_label);
|
||||
if (label == "none")
|
||||
return DECOR_NONE;
|
||||
if (label == "normal")
|
||||
return DECOR_NORMAL;
|
||||
if (label == "tiny")
|
||||
return DECOR_TINY;
|
||||
if (label == "tool")
|
||||
return DECOR_TOOL;
|
||||
if (label == "border")
|
||||
return DECOR_BORDER;
|
||||
if (label == "tab")
|
||||
return DECOR_TAB;
|
||||
int mask = -1;
|
||||
if ((str_label.size() > 1 && str_label[0] == '0' && str_label[1] == 'x') ||
|
||||
(str_label.size() > 0 && isdigit(str_label[0])))
|
||||
mask = strtol(str_label.c_str(), NULL, 0);
|
||||
return mask;
|
||||
}
|
||||
|
||||
bool FbWinFrame::useBorder() const {
|
||||
return !m_state.fullscreen && m_state.maximized != MAX_FULL &&
|
||||
(m_state.deco_mask & DECORM_BORDER);
|
||||
}
|
||||
|
||||
bool FbWinFrame::useTabs() const {
|
||||
return !m_state.fullscreen && m_state.deco_mask & DECORM_TAB;
|
||||
}
|
||||
|
||||
bool FbWinFrame::useTitlebar() const {
|
||||
return !m_state.fullscreen && m_state.deco_mask & DECORM_TITLEBAR;
|
||||
}
|
||||
|
||||
bool FbWinFrame::useHandle() const {
|
||||
return !m_state.fullscreen && !m_state.shaded &&
|
||||
m_state.deco_mask & DECORM_HANDLE;
|
||||
}
|
||||
|
||||
int FbWinFrame::getShape() const {
|
||||
int shape = theme()->shapePlace();
|
||||
if (!useTitlebar())
|
||||
if (!m_state.useTitlebar())
|
||||
shape &= ~(FbTk::Shape::TOPRIGHT|FbTk::Shape::TOPLEFT);
|
||||
if (!useHandle())
|
||||
if (!m_state.useHandle())
|
||||
shape &= ~(FbTk::Shape::BOTTOMRIGHT|FbTk::Shape::BOTTOMLEFT);
|
||||
return shape;
|
||||
}
|
||||
|
@ -1541,13 +1488,13 @@ void FbWinFrame::applyDecorations() {
|
|||
// 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 (useTabs())
|
||||
if (m_state.useTabs())
|
||||
client_move |= showTabs();
|
||||
else
|
||||
client_move |= hideTabs();
|
||||
|
||||
// we rely on frame not doing anything if it is already shown/hidden
|
||||
if (useTitlebar()) {
|
||||
if (m_state.useTitlebar()) {
|
||||
client_move |= showTitlebar();
|
||||
if (m_screen.getDefaultInternalTabs())
|
||||
client_move |= setTabMode(INTERNAL);
|
||||
|
@ -1555,11 +1502,11 @@ void FbWinFrame::applyDecorations() {
|
|||
client_move |= setTabMode(EXTERNAL);
|
||||
} else {
|
||||
client_move |= hideTitlebar();
|
||||
if (useTabs())
|
||||
if (m_state.useTabs())
|
||||
client_move |= setTabMode(EXTERNAL);
|
||||
}
|
||||
|
||||
if (useHandle())
|
||||
if (m_state.useHandle())
|
||||
client_move |= showHandle();
|
||||
else
|
||||
client_move |= hideHandle();
|
||||
|
@ -1581,7 +1528,7 @@ void FbWinFrame::applyDecorations() {
|
|||
|
||||
bool FbWinFrame::setBorderWidth(bool do_move) {
|
||||
unsigned int border_width = theme()->border().width();
|
||||
unsigned int win_bw = useBorder() ? border_width : 0;
|
||||
unsigned int win_bw = m_state.useBorder() ? border_width : 0;
|
||||
|
||||
if (border_width &&
|
||||
theme()->border().color().pixel() != window().borderColor()) {
|
||||
|
@ -1717,30 +1664,6 @@ void FbWinFrame::gravityTranslate(int &x, int &y,
|
|||
}
|
||||
}
|
||||
|
||||
int FbWinFrame::normalX() const {
|
||||
if ((m_state.maximized & MAX_HORZ) || m_state.fullscreen)
|
||||
return m_state.x;
|
||||
return x();
|
||||
}
|
||||
|
||||
int FbWinFrame::normalY() const {
|
||||
if ((m_state.maximized & MAX_VERT) || m_state.fullscreen)
|
||||
return m_state.y;
|
||||
return y();
|
||||
}
|
||||
|
||||
unsigned int FbWinFrame::normalWidth() const {
|
||||
if ((m_state.maximized & MAX_HORZ) || m_state.fullscreen)
|
||||
return m_state.width;
|
||||
return width();
|
||||
}
|
||||
|
||||
unsigned int FbWinFrame::normalHeight() const {
|
||||
if ((m_state.maximized & MAX_VERT) || m_state.fullscreen || m_state.shaded)
|
||||
return m_state.height;
|
||||
return height();
|
||||
}
|
||||
|
||||
int FbWinFrame::widthOffset() const {
|
||||
if (m_tabmode != EXTERNAL || !m_use_tabs)
|
||||
return 0;
|
||||
|
@ -1825,201 +1748,3 @@ void FbWinFrame::displaySize(unsigned int width, unsigned int height) const {
|
|||
width, height - titlebarHeight() - handleHeight());
|
||||
m_screen.showGeometry(i, j);
|
||||
}
|
||||
|
||||
void FbWinFrame::SizeHints::reset(const XSizeHints &sizehint) {
|
||||
if (sizehint.flags & PMinSize) {
|
||||
min_width = sizehint.min_width;
|
||||
min_height = sizehint.min_height;
|
||||
} else
|
||||
min_width = min_height = 1;
|
||||
|
||||
if (sizehint.flags & PBaseSize) {
|
||||
base_width = sizehint.base_width;
|
||||
base_height = sizehint.base_height;
|
||||
if (!(sizehint.flags & PMinSize)) {
|
||||
min_width = base_width;
|
||||
min_height = base_height;
|
||||
}
|
||||
} else
|
||||
base_width = base_height = 0;
|
||||
|
||||
if (sizehint.flags & PMaxSize) {
|
||||
max_width = sizehint.max_width;
|
||||
max_height = sizehint.max_height;
|
||||
} else
|
||||
max_width = max_height = 0; // unbounded
|
||||
|
||||
if (sizehint.flags & PResizeInc) {
|
||||
width_inc = sizehint.width_inc;
|
||||
height_inc = sizehint.height_inc;
|
||||
} else
|
||||
width_inc = height_inc = 1;
|
||||
|
||||
if (sizehint.flags & PAspect) {
|
||||
min_aspect_x = sizehint.min_aspect.x;
|
||||
min_aspect_y = sizehint.min_aspect.y;
|
||||
max_aspect_x = sizehint.max_aspect.x;
|
||||
max_aspect_y = sizehint.max_aspect.y;
|
||||
} else {
|
||||
min_aspect_x = max_aspect_y = 0;
|
||||
min_aspect_y = max_aspect_x = 1;
|
||||
}
|
||||
|
||||
if (sizehint.flags & PWinGravity)
|
||||
win_gravity = sizehint.win_gravity;
|
||||
else
|
||||
win_gravity = NorthWestGravity;
|
||||
|
||||
// some sanity checks
|
||||
if (width_inc == 0)
|
||||
width_inc = 1;
|
||||
if (height_inc == 0)
|
||||
height_inc = 1;
|
||||
|
||||
if (base_width > min_width)
|
||||
min_width = base_width;
|
||||
if (base_height > min_height)
|
||||
min_height = base_height;
|
||||
}
|
||||
|
||||
/* For aspect ratios
|
||||
Note that its slightly simplified in that only the
|
||||
line gradient is given - this is because for aspect
|
||||
ratios, we always have the line going through the origin
|
||||
|
||||
* Based on this formula:
|
||||
http://astronomy.swin.edu.au/~pbourke/geometry/pointline/
|
||||
|
||||
Note that a gradient from origin goes through ( grad , 1 )
|
||||
*/
|
||||
|
||||
void closestPointToAspect(unsigned int &ret_x, unsigned int &ret_y,
|
||||
unsigned int point_x, unsigned int point_y,
|
||||
unsigned int aspect_x, unsigned int aspect_y) {
|
||||
double u = static_cast<double>(point_x * aspect_x + point_y * aspect_y) /
|
||||
static_cast<double>(aspect_x * aspect_x + aspect_y * aspect_y);
|
||||
|
||||
ret_x = static_cast<unsigned int>(u * aspect_x);
|
||||
ret_y = static_cast<unsigned int>(u * aspect_y);
|
||||
}
|
||||
|
||||
unsigned int increaseToMultiple(unsigned int val, unsigned int inc) {
|
||||
return val % inc ? val + inc - (val % inc) : val;
|
||||
}
|
||||
|
||||
unsigned int decreaseToMultiple(unsigned int val, unsigned int inc) {
|
||||
return val % inc ? val - (val % inc) : val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes width and height to the nearest (lower) value
|
||||
* that conforms to it's size hints.
|
||||
*
|
||||
* display_* give the values that would be displayed
|
||||
* to the user when resizing.
|
||||
* We use pointers for display_* since they are optional.
|
||||
*
|
||||
* See ICCCM section 4.1.2.3
|
||||
*/
|
||||
void FbWinFrame::SizeHints::apply(unsigned int &width, unsigned int &height,
|
||||
bool make_fit) const {
|
||||
|
||||
/* aspect ratios are applied exclusive to the base size
|
||||
*
|
||||
* min_aspect_x width max_aspect_x
|
||||
* ------------ < ------- < ------------
|
||||
* min_aspect_y height max_aspect_y
|
||||
*
|
||||
* The trick is how to get back to the aspect ratio with minimal
|
||||
* change - do we modify x, y or both?
|
||||
* A: we minimise the distance between the current point, and
|
||||
* the target aspect ratio (consider them as x,y coordinates)
|
||||
* Consider that the aspect ratio is a line, and the current
|
||||
* w/h is a point, so we're just using the formula for
|
||||
* shortest distance from a point to a line!
|
||||
*/
|
||||
|
||||
// make respective to base_size
|
||||
unsigned int w = width - base_width, h = height - base_height;
|
||||
|
||||
if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h) {
|
||||
closestPointToAspect(w, h, w, h, min_aspect_x, min_aspect_y);
|
||||
// new w must be > old w, new h must be < old h
|
||||
w = increaseToMultiple(w, width_inc);
|
||||
h = decreaseToMultiple(h, height_inc);
|
||||
} else if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h) {
|
||||
closestPointToAspect(w, h, w, h, max_aspect_x, max_aspect_y);
|
||||
// new w must be < old w, new h must be > old h
|
||||
w = decreaseToMultiple(w, width_inc);
|
||||
h = increaseToMultiple(h, height_inc);
|
||||
}
|
||||
|
||||
// Check minimum size
|
||||
if (w + base_width < min_width) {
|
||||
w = increaseToMultiple(min_width - base_width, width_inc);
|
||||
// need to check maximum aspect again
|
||||
if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h)
|
||||
h = increaseToMultiple(w * max_aspect_y / max_aspect_x, height_inc);
|
||||
}
|
||||
|
||||
if (h + base_height < min_height) {
|
||||
h = increaseToMultiple(min_height - base_height, height_inc);
|
||||
// need to check minimum aspect again
|
||||
if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h)
|
||||
w = increaseToMultiple(h * min_aspect_x / min_aspect_y, width_inc);
|
||||
}
|
||||
|
||||
unsigned int max_w = make_fit && (width < max_width || max_width == 0) ?
|
||||
width : max_width;
|
||||
unsigned int max_h = make_fit && (height < max_height || max_height == 0) ?
|
||||
height : max_height;
|
||||
|
||||
// Check maximum size
|
||||
if (max_w > 0 && w + base_width > max_w)
|
||||
w = max_w - base_width;
|
||||
|
||||
if (max_h > 0 && h + base_height > max_h)
|
||||
h = max_h - base_height;
|
||||
|
||||
w = decreaseToMultiple(w, width_inc);
|
||||
h = decreaseToMultiple(h, height_inc);
|
||||
|
||||
// need to check aspects one more time
|
||||
if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h)
|
||||
h = decreaseToMultiple(w * min_aspect_y / min_aspect_x, height_inc);
|
||||
|
||||
if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h)
|
||||
w = decreaseToMultiple(h * max_aspect_x / max_aspect_y, width_inc);
|
||||
|
||||
width = w + base_width;
|
||||
height = h + base_height;
|
||||
}
|
||||
|
||||
// check if the given width and height satisfy the size hints
|
||||
bool FbWinFrame::SizeHints::valid(unsigned int w, unsigned int h) const {
|
||||
if (w < min_width || h < min_height)
|
||||
return false;
|
||||
|
||||
if (w > max_width || h > max_height)
|
||||
return false;
|
||||
|
||||
if ((w - base_width) % width_inc != 0)
|
||||
return false;
|
||||
|
||||
if ((h - base_height) % height_inc != 0)
|
||||
return false;
|
||||
|
||||
if (min_aspect_x * (h - base_height) > (w - base_width) * min_aspect_y)
|
||||
return false;
|
||||
|
||||
if (max_aspect_x * (h - base_height) < (w - base_width) * max_aspect_y)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FbWinFrame::SizeHints::displaySize(unsigned int &i, unsigned int &j,
|
||||
unsigned int width, unsigned int height) const {
|
||||
i = (width - base_width) / width_inc;
|
||||
j = (height - base_height) / height_inc;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include "FbTk/Container.hh"
|
||||
#include "FbTk/Shape.hh"
|
||||
|
||||
#include "WindowState.hh"
|
||||
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#include <vector>
|
||||
|
@ -68,85 +70,6 @@ public:
|
|||
RIGHTBOTTOM, RIGHT, RIGHTTOP
|
||||
};
|
||||
|
||||
/**
|
||||
* Types of maximization
|
||||
*/
|
||||
enum MaximizeMode {
|
||||
MAX_NONE = 0, ///< normal state
|
||||
MAX_HORZ = 1, ///< maximize horizontal
|
||||
MAX_VERT = 2, ///< maximize vertical
|
||||
MAX_FULL = 3 ///< maximize full
|
||||
};
|
||||
|
||||
/**
|
||||
This enumeration represents individual decoration
|
||||
attributes, they can be OR-d together to get a mask.
|
||||
Useful for saving.
|
||||
*/
|
||||
enum DecorationMask {
|
||||
DECORM_TITLEBAR = (1<<0),
|
||||
DECORM_HANDLE = (1<<1),
|
||||
DECORM_BORDER = (1<<2),
|
||||
DECORM_ICONIFY = (1<<3),
|
||||
DECORM_MAXIMIZE = (1<<4),
|
||||
DECORM_CLOSE = (1<<5),
|
||||
DECORM_MENU = (1<<6),
|
||||
DECORM_STICKY = (1<<7),
|
||||
DECORM_SHADE = (1<<8),
|
||||
DECORM_TAB = (1<<9),
|
||||
DECORM_ENABLED = (1<<10),
|
||||
DECORM_LAST = (1<<11) // useful for getting "All"
|
||||
};
|
||||
|
||||
enum Decoration {
|
||||
DECOR_NONE = 0,
|
||||
DECOR_NORMAL = DECORM_LAST - 1,
|
||||
DECOR_TINY = DECORM_TITLEBAR|DECORM_ICONIFY|DECORM_MENU|DECORM_TAB,
|
||||
DECOR_TOOL = DECORM_TITLEBAR|DECORM_MENU,
|
||||
DECOR_BORDER = DECORM_BORDER|DECORM_MENU,
|
||||
DECOR_TAB = DECORM_BORDER|DECORM_MENU|DECORM_TAB
|
||||
};
|
||||
|
||||
class SizeHints {
|
||||
public:
|
||||
SizeHints():
|
||||
min_width(1), max_width(0), min_height(1), max_height(0),
|
||||
width_inc(1), height_inc(1), base_width(0), base_height(0),
|
||||
min_aspect_x(0), max_aspect_x(1),
|
||||
min_aspect_y(1), max_aspect_y(0),
|
||||
win_gravity(0) { }
|
||||
|
||||
void reset(const XSizeHints &sizehint);
|
||||
|
||||
void apply(unsigned int &w, unsigned int &h,
|
||||
bool maximizing = false) const;
|
||||
bool valid(unsigned int width, unsigned int height) const;
|
||||
void displaySize(unsigned int &i, unsigned int &j,
|
||||
unsigned int width, unsigned int height) const;
|
||||
|
||||
unsigned int min_width, max_width, min_height, max_height,
|
||||
width_inc, height_inc, base_width, base_height,
|
||||
min_aspect_x, max_aspect_x, min_aspect_y, max_aspect_y;
|
||||
int win_gravity;
|
||||
};
|
||||
|
||||
class State {
|
||||
public:
|
||||
State():
|
||||
size_hints(),
|
||||
deco_mask(DECOR_NORMAL),
|
||||
focused(false),
|
||||
shaded(false), fullscreen(false), maximized(0),
|
||||
x(0), y(0), width(1), height(1) { }
|
||||
|
||||
SizeHints size_hints;
|
||||
unsigned int deco_mask;
|
||||
bool focused, shaded, fullscreen;
|
||||
int maximized;
|
||||
int x, y;
|
||||
unsigned int width, height;
|
||||
};
|
||||
|
||||
/// create a top level window
|
||||
FbWinFrame(BScreen &screen, FocusableTheme<FbWinFrameTheme> &theme,
|
||||
FbTk::ImageControl &imgctrl,
|
||||
|
@ -247,18 +170,9 @@ public:
|
|||
bool maximizing = false) const;
|
||||
void displaySize(unsigned int width, unsigned int height) const;
|
||||
|
||||
static int getDecoMaskFromString(const std::string &str);
|
||||
void setDecorationMask(unsigned int mask) { m_state.deco_mask = mask; }
|
||||
void applyDecorations();
|
||||
void applyState();
|
||||
void saveGeometry();
|
||||
|
||||
/// determine if the given decoration should be shown in current state
|
||||
bool useBorder() const;
|
||||
bool useTabs() const;
|
||||
bool useTitlebar() const;
|
||||
bool useHandle() const;
|
||||
int getShape() const;
|
||||
|
||||
// this function translates its arguments according to win_gravity
|
||||
// if win_gravity is negative, it does an inverse translation
|
||||
|
@ -287,10 +201,10 @@ public:
|
|||
unsigned int width() const { return m_window.width(); }
|
||||
unsigned int height() const { return m_window.height(); }
|
||||
|
||||
int normalX() const;
|
||||
int normalY() const;
|
||||
unsigned int normalWidth() const;
|
||||
unsigned int normalHeight() const;
|
||||
int normalX() const { return m_state.x; }
|
||||
int normalY() const { return m_state.y; }
|
||||
unsigned int normalWidth() const { return m_state.width; }
|
||||
unsigned int normalHeight() const { return m_state.height; }
|
||||
|
||||
// extra bits for tabs
|
||||
int xOffset() const;
|
||||
|
@ -368,6 +282,9 @@ private:
|
|||
bool showHandle();
|
||||
bool setBorderWidth(bool do_move = true);
|
||||
|
||||
// check which corners should be rounded
|
||||
int getShape() const;
|
||||
|
||||
/**
|
||||
@name apply pixmaps depending on focus
|
||||
*/
|
||||
|
@ -463,7 +380,7 @@ private:
|
|||
TabMode m_tabmode;
|
||||
|
||||
unsigned int m_active_orig_client_bw;
|
||||
State m_state;
|
||||
WindowState m_state;
|
||||
|
||||
bool m_need_render;
|
||||
int m_button_size; ///< size for all titlebar buttons
|
||||
|
|
|
@ -113,7 +113,7 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \
|
|||
Slit.cc Slit.hh SlitTheme.hh SlitTheme.cc SlitClient.hh SlitClient.cc \
|
||||
WinButton.hh WinButton.cc \
|
||||
WinButtonTheme.hh WinButtonTheme.cc \
|
||||
Window.cc Window.hh \
|
||||
Window.cc Window.hh WindowState.cc WindowState.hh\
|
||||
Workspace.cc Workspace.hh \
|
||||
FbCommands.hh FbCommands.cc LayerMenu.hh LayerMenu.cc \
|
||||
Layer.hh \
|
||||
|
|
|
@ -500,7 +500,7 @@ int parseApp(ifstream &file, Application &app, string *first_line = 0) {
|
|||
app.rememberIconHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0));
|
||||
app.rememberFocusHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0));
|
||||
} else if (str_key == "deco") {
|
||||
int deco = FbWinFrame::getDecoMaskFromString(str_label);
|
||||
int deco = WindowState::getDecoMaskFromString(str_label);
|
||||
if (deco == -1)
|
||||
had_error = 1;
|
||||
else
|
||||
|
@ -535,13 +535,13 @@ int parseApp(ifstream &file, Application &app, string *first_line = 0) {
|
|||
app.rememberMinimizedstate((strcasecmp(str_label.c_str(), "yes") == 0));
|
||||
} else if (str_key == "maximized") {
|
||||
if (strcasecmp(str_label.c_str(), "yes") == 0)
|
||||
app.rememberMaximizedstate(FbWinFrame::MAX_FULL);
|
||||
app.rememberMaximizedstate(WindowState::MAX_FULL);
|
||||
else if (strcasecmp(str_label.c_str(), "horz") == 0)
|
||||
app.rememberMaximizedstate(FbWinFrame::MAX_HORZ);
|
||||
app.rememberMaximizedstate(WindowState::MAX_HORZ);
|
||||
else if (strcasecmp(str_label.c_str(), "vert") == 0)
|
||||
app.rememberMaximizedstate(FbWinFrame::MAX_VERT);
|
||||
app.rememberMaximizedstate(WindowState::MAX_VERT);
|
||||
else
|
||||
app.rememberMaximizedstate(FbWinFrame::MAX_NONE);
|
||||
app.rememberMaximizedstate(WindowState::MAX_NONE);
|
||||
} else if (str_key == "fullscreen") {
|
||||
app.rememberFullscreenstate((strcasecmp(str_label.c_str(), "yes") == 0));
|
||||
} else if (str_key == "jump") {
|
||||
|
@ -953,25 +953,25 @@ void Remember::save() {
|
|||
apps_file << " [Deco]\t{NONE}" << endl;
|
||||
break;
|
||||
case (0xffffffff):
|
||||
case (FbWinFrame::DECORM_LAST - 1):
|
||||
case (WindowState::DECORM_LAST - 1):
|
||||
apps_file << " [Deco]\t{NORMAL}" << endl;
|
||||
break;
|
||||
case (FbWinFrame::DECORM_TITLEBAR
|
||||
| FbWinFrame::DECORM_ICONIFY
|
||||
| FbWinFrame::DECORM_MENU):
|
||||
case (WindowState::DECORM_TITLEBAR
|
||||
| WindowState::DECORM_ICONIFY
|
||||
| WindowState::DECORM_MENU):
|
||||
apps_file << " [Deco]\t{TOOL}" << endl;
|
||||
break;
|
||||
case (FbWinFrame::DECORM_TITLEBAR
|
||||
| FbWinFrame::DECORM_MENU):
|
||||
case (WindowState::DECORM_TITLEBAR
|
||||
| WindowState::DECORM_MENU):
|
||||
apps_file << " [Deco]\t{TINY}" << endl;
|
||||
break;
|
||||
case (FbWinFrame::DECORM_BORDER
|
||||
| FbWinFrame::DECORM_MENU):
|
||||
case (WindowState::DECORM_BORDER
|
||||
| WindowState::DECORM_MENU):
|
||||
apps_file << " [Deco]\t{BORDER}" << endl;
|
||||
break;
|
||||
case (FbWinFrame::DECORM_BORDER
|
||||
| FbWinFrame::DECORM_MENU
|
||||
| FbWinFrame::DECORM_TAB):
|
||||
case (WindowState::DECORM_BORDER
|
||||
| WindowState::DECORM_MENU
|
||||
| WindowState::DECORM_TAB):
|
||||
apps_file << " [Deco]\t{TAB}" << endl;
|
||||
break;
|
||||
default:
|
||||
|
@ -999,16 +999,16 @@ void Remember::save() {
|
|||
if (a.maximizedstate_remember) {
|
||||
apps_file << " [Maximized]\t{";
|
||||
switch (a.maximizedstate) {
|
||||
case FbWinFrame::MAX_FULL:
|
||||
case WindowState::MAX_FULL:
|
||||
apps_file << "yes" << "}" << endl;
|
||||
break;
|
||||
case FbWinFrame::MAX_HORZ:
|
||||
case WindowState::MAX_HORZ:
|
||||
apps_file << "horz" << "}" << endl;
|
||||
break;
|
||||
case FbWinFrame::MAX_VERT:
|
||||
case WindowState::MAX_VERT:
|
||||
apps_file << "vert" << "}" << endl;
|
||||
break;
|
||||
case FbWinFrame::MAX_NONE:
|
||||
case WindowState::MAX_NONE:
|
||||
default:
|
||||
apps_file << "no" << "}" << endl;
|
||||
break;
|
||||
|
|
|
@ -22,8 +22,9 @@
|
|||
#ifndef WINCLIENT_HH
|
||||
#define WINCLIENT_HH
|
||||
|
||||
#include "FbWinFrame.hh"
|
||||
#include "Window.hh"
|
||||
#include "WindowState.hh"
|
||||
|
||||
#include "FbTk/FbWindow.hh"
|
||||
#include "FbTk/FbString.hh"
|
||||
|
||||
|
@ -114,7 +115,7 @@ public:
|
|||
Window getGroupLeftWindow() const;
|
||||
|
||||
const MwmHints *getMwmHint() const { return m_mwm_hint; }
|
||||
const FbWinFrame::SizeHints &sizeHints() const { return m_size_hints; }
|
||||
const SizeHints &sizeHints() const { return m_size_hints; }
|
||||
|
||||
unsigned int minWidth() const { return m_size_hints.min_width; }
|
||||
unsigned int minHeight() const { return m_size_hints.min_height; }
|
||||
|
@ -157,7 +158,7 @@ private:
|
|||
|
||||
Focusable::WindowType m_window_type;
|
||||
MwmHints *m_mwm_hint;
|
||||
FbWinFrame::SizeHints m_size_hints;
|
||||
SizeHints m_size_hints;
|
||||
|
||||
Strut *m_strut;
|
||||
// map transient_for X window to winclient transient
|
||||
|
|
|
@ -271,7 +271,7 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbTk::XLayer &layer):
|
|||
m_creation_time(0),
|
||||
moving(false), resizing(false), shaded(false), iconic(false),
|
||||
stuck(false), m_initialized(false), fullscreen(false),
|
||||
maximized(FbWinFrame::MAX_NONE),
|
||||
maximized(WindowState::MAX_NONE),
|
||||
m_attaching_tab(0),
|
||||
display(FbTk::App::instance()->display()),
|
||||
m_button_grab_x(0), m_button_grab_y(0),
|
||||
|
@ -423,7 +423,7 @@ void FluxboxWindow::init() {
|
|||
m_workspace_number = m_screen.currentWorkspaceID();
|
||||
|
||||
// set default decorations but don't apply them
|
||||
setDecorationMask(FbWinFrame::getDecoMaskFromString(screen().defaultDeco()),
|
||||
setDecorationMask(WindowState::getDecoMaskFromString(screen().defaultDeco()),
|
||||
false);
|
||||
|
||||
functions.resize = functions.move = functions.iconify = functions.maximize
|
||||
|
@ -559,7 +559,7 @@ void FluxboxWindow::init() {
|
|||
|
||||
if (maximized) {
|
||||
int tmp = maximized;
|
||||
maximized = FbWinFrame::MAX_NONE;
|
||||
maximized = WindowState::MAX_NONE;
|
||||
setMaximizedState(tmp);
|
||||
}
|
||||
|
||||
|
@ -1045,7 +1045,7 @@ void FluxboxWindow::updateSizeHints() {
|
|||
if ((*it) == m_client)
|
||||
continue;
|
||||
|
||||
const FbWinFrame::SizeHints &hint = (*it)->sizeHints();
|
||||
const SizeHints &hint = (*it)->sizeHints();
|
||||
if (m_size_hint.min_width < hint.min_width)
|
||||
m_size_hint.min_width = hint.min_width;
|
||||
if (m_size_hint.max_width > hint.max_width)
|
||||
|
@ -1144,7 +1144,7 @@ void FluxboxWindow::updateMWMHintsFromClient(WinClient &client) {
|
|||
}
|
||||
|
||||
unsigned int mask = decorationMask();
|
||||
mask &= FbWinFrame::getDecoMaskFromString(screen().defaultDeco());
|
||||
mask &= WindowState::getDecoMaskFromString(screen().defaultDeco());
|
||||
setDecorationMask(mask, false);
|
||||
|
||||
// functions.tabable is ours, not special one
|
||||
|
@ -1503,7 +1503,7 @@ void FluxboxWindow::setFullscreenLayer() {
|
|||
void FluxboxWindow::maximize(int type) {
|
||||
|
||||
// nothing to do
|
||||
if (type == FbWinFrame::MAX_NONE)
|
||||
if (type == WindowState::MAX_NONE)
|
||||
return;
|
||||
|
||||
int new_max = maximized;
|
||||
|
@ -1512,14 +1512,14 @@ void FluxboxWindow::maximize(int type) {
|
|||
// when _don't_ we want to toggle?
|
||||
// - type is horizontal maximise, or
|
||||
// - type is full and we are not maximised horz but already vertically
|
||||
if (type != FbWinFrame::MAX_HORZ &&
|
||||
(type != FbWinFrame::MAX_FULL || maximized != FbWinFrame::MAX_VERT))
|
||||
new_max ^= FbWinFrame::MAX_VERT;
|
||||
if (type != WindowState::MAX_HORZ &&
|
||||
(type != WindowState::MAX_FULL || maximized != WindowState::MAX_VERT))
|
||||
new_max ^= WindowState::MAX_VERT;
|
||||
|
||||
// maximize horizontally?
|
||||
if (type != FbWinFrame::MAX_VERT &&
|
||||
(type != FbWinFrame::MAX_FULL || maximized != FbWinFrame::MAX_HORZ))
|
||||
new_max ^= FbWinFrame::MAX_HORZ;
|
||||
if (type != WindowState::MAX_VERT &&
|
||||
(type != WindowState::MAX_FULL || maximized != WindowState::MAX_HORZ))
|
||||
new_max ^= WindowState::MAX_HORZ;
|
||||
|
||||
setMaximizedState(new_max);
|
||||
}
|
||||
|
@ -1552,21 +1552,21 @@ void FluxboxWindow::setMaximizedState(int type) {
|
|||
* Maximize window horizontal
|
||||
*/
|
||||
void FluxboxWindow::maximizeHorizontal() {
|
||||
maximize(FbWinFrame::MAX_HORZ);
|
||||
maximize(WindowState::MAX_HORZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximize window vertical
|
||||
*/
|
||||
void FluxboxWindow::maximizeVertical() {
|
||||
maximize(FbWinFrame::MAX_VERT);
|
||||
maximize(WindowState::MAX_VERT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximize window fully
|
||||
*/
|
||||
void FluxboxWindow::maximizeFull() {
|
||||
maximize(FbWinFrame::MAX_FULL);
|
||||
maximize(WindowState::MAX_FULL);
|
||||
}
|
||||
|
||||
void FluxboxWindow::setWorkspace(int n) {
|
||||
|
@ -2807,9 +2807,9 @@ void FluxboxWindow::toggleDecoration() {
|
|||
if (m_toggled_decos) {
|
||||
m_old_decoration_mask = decorationMask();
|
||||
if (decorations.titlebar | decorations.tab)
|
||||
setDecorationMask(FbWinFrame::DECOR_NONE);
|
||||
setDecorationMask(WindowState::DECOR_NONE);
|
||||
else
|
||||
setDecorationMask(FbWinFrame::DECOR_NORMAL);
|
||||
setDecorationMask(WindowState::DECOR_NORMAL);
|
||||
} else //revert back to old decoration
|
||||
setDecorationMask(m_old_decoration_mask);
|
||||
|
||||
|
@ -2818,42 +2818,42 @@ void FluxboxWindow::toggleDecoration() {
|
|||
unsigned int FluxboxWindow::decorationMask() const {
|
||||
unsigned int ret = 0;
|
||||
if (decorations.titlebar)
|
||||
ret |= FbWinFrame::DECORM_TITLEBAR;
|
||||
ret |= WindowState::DECORM_TITLEBAR;
|
||||
if (decorations.handle)
|
||||
ret |= FbWinFrame::DECORM_HANDLE;
|
||||
ret |= WindowState::DECORM_HANDLE;
|
||||
if (decorations.border)
|
||||
ret |= FbWinFrame::DECORM_BORDER;
|
||||
ret |= WindowState::DECORM_BORDER;
|
||||
if (decorations.iconify)
|
||||
ret |= FbWinFrame::DECORM_ICONIFY;
|
||||
ret |= WindowState::DECORM_ICONIFY;
|
||||
if (decorations.maximize)
|
||||
ret |= FbWinFrame::DECORM_MAXIMIZE;
|
||||
ret |= WindowState::DECORM_MAXIMIZE;
|
||||
if (decorations.close)
|
||||
ret |= FbWinFrame::DECORM_CLOSE;
|
||||
ret |= WindowState::DECORM_CLOSE;
|
||||
if (decorations.menu)
|
||||
ret |= FbWinFrame::DECORM_MENU;
|
||||
ret |= WindowState::DECORM_MENU;
|
||||
if (decorations.sticky)
|
||||
ret |= FbWinFrame::DECORM_STICKY;
|
||||
ret |= WindowState::DECORM_STICKY;
|
||||
if (decorations.shade)
|
||||
ret |= FbWinFrame::DECORM_SHADE;
|
||||
ret |= WindowState::DECORM_SHADE;
|
||||
if (decorations.tab)
|
||||
ret |= FbWinFrame::DECORM_TAB;
|
||||
ret |= WindowState::DECORM_TAB;
|
||||
if (decorations.enabled)
|
||||
ret |= FbWinFrame::DECORM_ENABLED;
|
||||
ret |= WindowState::DECORM_ENABLED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FluxboxWindow::setDecorationMask(unsigned int mask, bool apply) {
|
||||
decorations.titlebar = mask & FbWinFrame::DECORM_TITLEBAR;
|
||||
decorations.handle = mask & FbWinFrame::DECORM_HANDLE;
|
||||
decorations.border = mask & FbWinFrame::DECORM_BORDER;
|
||||
decorations.iconify = mask & FbWinFrame::DECORM_ICONIFY;
|
||||
decorations.maximize = mask & FbWinFrame::DECORM_MAXIMIZE;
|
||||
decorations.close = mask & FbWinFrame::DECORM_CLOSE;
|
||||
decorations.menu = mask & FbWinFrame::DECORM_MENU;
|
||||
decorations.sticky = mask & FbWinFrame::DECORM_STICKY;
|
||||
decorations.shade = mask & FbWinFrame::DECORM_SHADE;
|
||||
decorations.tab = mask & FbWinFrame::DECORM_TAB;
|
||||
decorations.enabled = mask & FbWinFrame::DECORM_ENABLED;
|
||||
decorations.titlebar = mask & WindowState::DECORM_TITLEBAR;
|
||||
decorations.handle = mask & WindowState::DECORM_HANDLE;
|
||||
decorations.border = mask & WindowState::DECORM_BORDER;
|
||||
decorations.iconify = mask & WindowState::DECORM_ICONIFY;
|
||||
decorations.maximize = mask & WindowState::DECORM_MAXIMIZE;
|
||||
decorations.close = mask & WindowState::DECORM_CLOSE;
|
||||
decorations.menu = mask & WindowState::DECORM_MENU;
|
||||
decorations.sticky = mask & WindowState::DECORM_STICKY;
|
||||
decorations.shade = mask & WindowState::DECORM_SHADE;
|
||||
decorations.tab = mask & WindowState::DECORM_TAB;
|
||||
decorations.enabled = mask & WindowState::DECORM_ENABLED;
|
||||
// we don't want to do this during initialization
|
||||
if (apply)
|
||||
applyDecorations();
|
||||
|
@ -3024,7 +3024,7 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) {
|
|||
// we only care about the left/top etc that includes borders
|
||||
int borderW = 0;
|
||||
|
||||
if (decorationMask() & (FbWinFrame::DECORM_BORDER|FbWinFrame::DECORM_HANDLE))
|
||||
if (decorationMask() & (WindowState::DECORM_BORDER|WindowState::DECORM_HANDLE))
|
||||
borderW = frame().window().borderWidth();
|
||||
|
||||
int top = orig_top; // orig include the borders
|
||||
|
@ -3096,7 +3096,7 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) {
|
|||
if ((*it) == this)
|
||||
continue; // skip myself
|
||||
|
||||
bw = (*it)->decorationMask() & (FbWinFrame::DECORM_BORDER|FbWinFrame::DECORM_HANDLE) ?
|
||||
bw = (*it)->decorationMask() & (WindowState::DECORM_BORDER|WindowState::DECORM_HANDLE) ?
|
||||
(*it)->frame().window().borderWidth() : 0;
|
||||
|
||||
snapToWindow(dx, dy, left, right, top, bottom,
|
||||
|
@ -3175,7 +3175,7 @@ void FluxboxWindow::startResizing(int x, int y, ReferenceCorner dir) {
|
|||
m_resize_corner = dir;
|
||||
|
||||
resizing = true;
|
||||
maximized = FbWinFrame::MAX_NONE;
|
||||
maximized = WindowState::MAX_NONE;
|
||||
frame().setMaximized(maximized);
|
||||
|
||||
const Cursor& cursor = (m_resize_corner == LEFTTOP) ? frame().theme()->upperLeftAngleCursor() :
|
||||
|
@ -3862,7 +3862,7 @@ void FluxboxWindow::setWindowType(Focusable::WindowType type) {
|
|||
setFocusNew(false);
|
||||
setMouseFocus(false);
|
||||
setClickFocus(false);
|
||||
setDecorationMask(FbWinFrame::DECOR_NONE);
|
||||
setDecorationMask(WindowState::DECOR_NONE);
|
||||
moveToLayer(::Layer::DOCK);
|
||||
break;
|
||||
case Focusable::TYPE_DESKTOP:
|
||||
|
@ -3877,7 +3877,7 @@ void FluxboxWindow::setWindowType(Focusable::WindowType type) {
|
|||
setFocusNew(false);
|
||||
setMouseFocus(false);
|
||||
moveToLayer(::Layer::DESKTOP);
|
||||
setDecorationMask(FbWinFrame::DECOR_NONE);
|
||||
setDecorationMask(WindowState::DECOR_NONE);
|
||||
setTabable(false);
|
||||
setMovable(false);
|
||||
setResizable(false);
|
||||
|
@ -3889,7 +3889,7 @@ void FluxboxWindow::setWindowType(Focusable::WindowType type) {
|
|||
* window is a splash screen displayed as an application
|
||||
* is starting up.
|
||||
*/
|
||||
setDecorationMask(FbWinFrame::DECOR_NONE);
|
||||
setDecorationMask(WindowState::DECOR_NONE);
|
||||
setFocusHidden(true);
|
||||
setIconHidden(true);
|
||||
setFocusNew(false);
|
||||
|
@ -3909,7 +3909,7 @@ void FluxboxWindow::setWindowType(Focusable::WindowType type) {
|
|||
* application). Windows of this type may set the
|
||||
* WM_TRANSIENT_FOR hint indicating the main application window.
|
||||
*/
|
||||
setDecorationMask(FbWinFrame::DECOR_TOOL);
|
||||
setDecorationMask(WindowState::DECOR_TOOL);
|
||||
setIconHidden(true);
|
||||
moveToLayer(::Layer::ABOVE_DOCK);
|
||||
break;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "FbTk/Observer.hh"
|
||||
#include "FbTk/EventHandler.hh"
|
||||
#include "FbTk/XLayerItem.hh"
|
||||
|
||||
#include "FbWinFrame.hh"
|
||||
#include "Focusable.hh"
|
||||
#include "FocusableTheme.hh"
|
||||
|
@ -45,7 +46,6 @@
|
|||
class WinClient;
|
||||
class FbWinFrameTheme;
|
||||
class BScreen;
|
||||
class FbWinFrame;
|
||||
class FocusControl;
|
||||
class FbMenu;
|
||||
|
||||
|
@ -212,7 +212,7 @@ public:
|
|||
/// set fullscreen
|
||||
void setFullscreen(bool flag);
|
||||
/// toggle maximize
|
||||
void maximize(int type = FbWinFrame::MAX_FULL);
|
||||
void maximize(int type = WindowState::MAX_FULL);
|
||||
/// sets the maximized state
|
||||
void setMaximizedState(int type);
|
||||
/// maximizes the window horizontal
|
||||
|
@ -373,9 +373,9 @@ public:
|
|||
bool isIconic() const { return iconic; }
|
||||
bool isShaded() const { return shaded; }
|
||||
bool isFullscreen() const { return fullscreen; }
|
||||
bool isMaximized() const { return maximized == FbWinFrame::MAX_FULL; }
|
||||
bool isMaximizedVert() const { return (bool)(maximized & FbWinFrame::MAX_VERT); }
|
||||
bool isMaximizedHorz() const { return (bool)(maximized & FbWinFrame::MAX_HORZ); }
|
||||
bool isMaximized() const { return maximized == WindowState::MAX_FULL; }
|
||||
bool isMaximizedVert() const { return (bool)(maximized & WindowState::MAX_VERT); }
|
||||
bool isMaximizedHorz() const { return (bool)(maximized & WindowState::MAX_HORZ); }
|
||||
int maximizedState() const { return maximized; }
|
||||
bool isIconifiable() const { return functions.iconify; }
|
||||
bool isMaximizable() const { return functions.maximize; }
|
||||
|
@ -553,7 +553,7 @@ private:
|
|||
typedef std::map<WinClient *, IconButton *> Client2ButtonMap;
|
||||
Client2ButtonMap m_labelbuttons;
|
||||
|
||||
FbWinFrame::SizeHints m_size_hint;
|
||||
SizeHints m_size_hint;
|
||||
struct _decorations {
|
||||
bool titlebar, handle, border, iconify,
|
||||
maximize, close, menu, sticky, shade, tab, enabled;
|
||||
|
|
266
src/WindowState.cc
Normal file
266
src/WindowState.cc
Normal file
|
@ -0,0 +1,266 @@
|
|||
// WindowState.cc
|
||||
// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include "WindowState.hh"
|
||||
|
||||
#include "FbTk/StringUtil.hh"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
bool WindowState::useBorder() const {
|
||||
return !fullscreen && maximized != MAX_FULL && deco_mask & DECORM_BORDER;
|
||||
}
|
||||
|
||||
bool WindowState::useHandle() const {
|
||||
return !fullscreen && !shaded && deco_mask & DECORM_HANDLE;
|
||||
}
|
||||
|
||||
bool WindowState::useTabs() const {
|
||||
return !fullscreen && deco_mask & DECORM_TAB;
|
||||
}
|
||||
|
||||
bool WindowState::useTitlebar() const {
|
||||
return !fullscreen && deco_mask & DECORM_TITLEBAR;
|
||||
}
|
||||
|
||||
void WindowState::saveGeometry(int new_x, int new_y,
|
||||
unsigned int new_w, unsigned int new_h) {
|
||||
if (fullscreen || maximized == MAX_FULL)
|
||||
return;
|
||||
|
||||
if (!(maximized & MAX_HORZ)) {
|
||||
x = new_x;
|
||||
width = new_w;
|
||||
}
|
||||
if (!(maximized & MAX_VERT)) {
|
||||
y = new_y;
|
||||
if (!shaded)
|
||||
height = new_h;
|
||||
}
|
||||
}
|
||||
|
||||
int WindowState::getDecoMaskFromString(const std::string &str_label) {
|
||||
std::string label = FbTk::StringUtil::toLower(str_label);
|
||||
if (label == "none")
|
||||
return DECOR_NONE;
|
||||
if (label == "normal")
|
||||
return DECOR_NORMAL;
|
||||
if (label == "tiny")
|
||||
return DECOR_TINY;
|
||||
if (label == "tool")
|
||||
return DECOR_TOOL;
|
||||
if (label == "border")
|
||||
return DECOR_BORDER;
|
||||
if (label == "tab")
|
||||
return DECOR_TAB;
|
||||
int mask = -1;
|
||||
if ((str_label.size() > 1 && str_label[0] == '0' && str_label[1] == 'x') ||
|
||||
(str_label.size() > 0 && isdigit(str_label[0])))
|
||||
mask = strtol(str_label.c_str(), NULL, 0);
|
||||
return mask;
|
||||
}
|
||||
|
||||
void SizeHints::reset(const XSizeHints &sizehint) {
|
||||
if (sizehint.flags & PMinSize) {
|
||||
min_width = sizehint.min_width;
|
||||
min_height = sizehint.min_height;
|
||||
} else
|
||||
min_width = min_height = 1;
|
||||
|
||||
if (sizehint.flags & PBaseSize) {
|
||||
base_width = sizehint.base_width;
|
||||
base_height = sizehint.base_height;
|
||||
if (!(sizehint.flags & PMinSize)) {
|
||||
min_width = base_width;
|
||||
min_height = base_height;
|
||||
}
|
||||
} else
|
||||
base_width = base_height = 0;
|
||||
|
||||
if (sizehint.flags & PMaxSize) {
|
||||
max_width = sizehint.max_width;
|
||||
max_height = sizehint.max_height;
|
||||
} else
|
||||
max_width = max_height = 0; // unbounded
|
||||
|
||||
if (sizehint.flags & PResizeInc) {
|
||||
width_inc = sizehint.width_inc;
|
||||
height_inc = sizehint.height_inc;
|
||||
} else
|
||||
width_inc = height_inc = 1;
|
||||
|
||||
if (sizehint.flags & PAspect) {
|
||||
min_aspect_x = sizehint.min_aspect.x;
|
||||
min_aspect_y = sizehint.min_aspect.y;
|
||||
max_aspect_x = sizehint.max_aspect.x;
|
||||
max_aspect_y = sizehint.max_aspect.y;
|
||||
} else {
|
||||
min_aspect_x = max_aspect_y = 0;
|
||||
min_aspect_y = max_aspect_x = 1;
|
||||
}
|
||||
|
||||
if (sizehint.flags & PWinGravity)
|
||||
win_gravity = sizehint.win_gravity;
|
||||
else
|
||||
win_gravity = NorthWestGravity;
|
||||
|
||||
// some sanity checks
|
||||
if (width_inc == 0)
|
||||
width_inc = 1;
|
||||
if (height_inc == 0)
|
||||
height_inc = 1;
|
||||
|
||||
if (base_width > min_width)
|
||||
min_width = base_width;
|
||||
if (base_height > min_height)
|
||||
min_height = base_height;
|
||||
}
|
||||
|
||||
void closestPointToAspect(unsigned int &ret_x, unsigned int &ret_y,
|
||||
unsigned int point_x, unsigned int point_y,
|
||||
unsigned int aspect_x, unsigned int aspect_y) {
|
||||
double u = static_cast<double>(point_x * aspect_x + point_y * aspect_y) /
|
||||
static_cast<double>(aspect_x * aspect_x + aspect_y * aspect_y);
|
||||
|
||||
ret_x = static_cast<unsigned int>(u * aspect_x);
|
||||
ret_y = static_cast<unsigned int>(u * aspect_y);
|
||||
}
|
||||
|
||||
unsigned int increaseToMultiple(unsigned int val, unsigned int inc) {
|
||||
return val % inc ? val + inc - (val % inc) : val;
|
||||
}
|
||||
|
||||
unsigned int decreaseToMultiple(unsigned int val, unsigned int inc) {
|
||||
return val % inc ? val - (val % inc) : val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes width and height to the nearest (lower) value
|
||||
* that conforms to it's size hints.
|
||||
*
|
||||
* display_* give the values that would be displayed
|
||||
* to the user when resizing.
|
||||
* We use pointers for display_* since they are optional.
|
||||
*
|
||||
* See ICCCM section 4.1.2.3
|
||||
*/
|
||||
void SizeHints::apply(unsigned int &width, unsigned int &height,
|
||||
bool make_fit) const {
|
||||
|
||||
/* aspect ratios are applied exclusive to the base size
|
||||
*
|
||||
* min_aspect_x width max_aspect_x
|
||||
* ------------ < ------- < ------------
|
||||
* min_aspect_y height max_aspect_y
|
||||
*
|
||||
* The trick is how to get back to the aspect ratio with minimal
|
||||
* change - do we modify x, y or both?
|
||||
* A: we minimise the distance between the current point, and
|
||||
* the target aspect ratio (consider them as x,y coordinates)
|
||||
* Consider that the aspect ratio is a line, and the current
|
||||
* w/h is a point, so we're just using the formula for
|
||||
* shortest distance from a point to a line!
|
||||
*/
|
||||
|
||||
// make respective to base_size
|
||||
unsigned int w = width - base_width, h = height - base_height;
|
||||
|
||||
if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h) {
|
||||
closestPointToAspect(w, h, w, h, min_aspect_x, min_aspect_y);
|
||||
// new w must be > old w, new h must be < old h
|
||||
w = increaseToMultiple(w, width_inc);
|
||||
h = decreaseToMultiple(h, height_inc);
|
||||
} else if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h) {
|
||||
closestPointToAspect(w, h, w, h, max_aspect_x, max_aspect_y);
|
||||
// new w must be < old w, new h must be > old h
|
||||
w = decreaseToMultiple(w, width_inc);
|
||||
h = increaseToMultiple(h, height_inc);
|
||||
}
|
||||
|
||||
// Check minimum size
|
||||
if (w + base_width < min_width) {
|
||||
w = increaseToMultiple(min_width - base_width, width_inc);
|
||||
// need to check maximum aspect again
|
||||
if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h)
|
||||
h = increaseToMultiple(w * max_aspect_y / max_aspect_x, height_inc);
|
||||
}
|
||||
|
||||
if (h + base_height < min_height) {
|
||||
h = increaseToMultiple(min_height - base_height, height_inc);
|
||||
// need to check minimum aspect again
|
||||
if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h)
|
||||
w = increaseToMultiple(h * min_aspect_x / min_aspect_y, width_inc);
|
||||
}
|
||||
|
||||
unsigned int max_w = make_fit && (width < max_width || max_width == 0) ?
|
||||
width : max_width;
|
||||
unsigned int max_h = make_fit && (height < max_height || max_height == 0) ?
|
||||
height : max_height;
|
||||
|
||||
// Check maximum size
|
||||
if (max_w > 0 && w + base_width > max_w)
|
||||
w = max_w - base_width;
|
||||
|
||||
if (max_h > 0 && h + base_height > max_h)
|
||||
h = max_h - base_height;
|
||||
|
||||
w = decreaseToMultiple(w, width_inc);
|
||||
h = decreaseToMultiple(h, height_inc);
|
||||
|
||||
// need to check aspects one more time
|
||||
if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h)
|
||||
h = decreaseToMultiple(w * min_aspect_y / min_aspect_x, height_inc);
|
||||
|
||||
if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h)
|
||||
w = decreaseToMultiple(h * max_aspect_x / max_aspect_y, width_inc);
|
||||
|
||||
width = w + base_width;
|
||||
height = h + base_height;
|
||||
}
|
||||
|
||||
// check if the given width and height satisfy the size hints
|
||||
bool SizeHints::valid(unsigned int w, unsigned int h) const {
|
||||
if (w < min_width || h < min_height)
|
||||
return false;
|
||||
|
||||
if (w > max_width || h > max_height)
|
||||
return false;
|
||||
|
||||
if ((w - base_width) % width_inc != 0)
|
||||
return false;
|
||||
|
||||
if ((h - base_height) % height_inc != 0)
|
||||
return false;
|
||||
|
||||
if (min_aspect_x * (h - base_height) > (w - base_width) * min_aspect_y)
|
||||
return false;
|
||||
|
||||
if (max_aspect_x * (h - base_height) < (w - base_width) * max_aspect_y)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SizeHints::displaySize(unsigned int &i, unsigned int &j,
|
||||
unsigned int width, unsigned int height) const {
|
||||
i = (width - base_width) / width_inc;
|
||||
j = (height - base_height) / height_inc;
|
||||
}
|
118
src/WindowState.hh
Normal file
118
src/WindowState.hh
Normal file
|
@ -0,0 +1,118 @@
|
|||
// WindowState.hh
|
||||
// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef WINDOWSTATE_HH
|
||||
#define WINDOWSTATE_HH
|
||||
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
class SizeHints {
|
||||
public:
|
||||
SizeHints():
|
||||
min_width(1), max_width(0), min_height(1), max_height(0),
|
||||
width_inc(1), height_inc(1), base_width(0), base_height(0),
|
||||
min_aspect_x(0), max_aspect_x(1),
|
||||
min_aspect_y(1), max_aspect_y(0),
|
||||
win_gravity(0) { }
|
||||
|
||||
void reset(const XSizeHints &sizehint);
|
||||
|
||||
void apply(unsigned int &w, unsigned int &h,
|
||||
bool maximizing = false) const;
|
||||
bool valid(unsigned int width, unsigned int height) const;
|
||||
void displaySize(unsigned int &i, unsigned int &j,
|
||||
unsigned int width, unsigned int height) const;
|
||||
|
||||
unsigned int min_width, max_width, min_height, max_height,
|
||||
width_inc, height_inc, base_width, base_height,
|
||||
min_aspect_x, max_aspect_x, min_aspect_y, max_aspect_y;
|
||||
int win_gravity;
|
||||
};
|
||||
|
||||
class WindowState {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Types of maximization
|
||||
*/
|
||||
enum MaximizeMode {
|
||||
MAX_NONE = 0, ///< normal state
|
||||
MAX_HORZ = 1, ///< maximize horizontal
|
||||
MAX_VERT = 2, ///< maximize vertical
|
||||
MAX_FULL = 3 ///< maximize full
|
||||
};
|
||||
|
||||
/**
|
||||
This enumeration represents individual decoration
|
||||
attributes, they can be OR-d together to get a mask.
|
||||
Useful for saving.
|
||||
*/
|
||||
enum DecorationMask {
|
||||
DECORM_TITLEBAR = (1<<0),
|
||||
DECORM_HANDLE = (1<<1),
|
||||
DECORM_BORDER = (1<<2),
|
||||
DECORM_ICONIFY = (1<<3),
|
||||
DECORM_MAXIMIZE = (1<<4),
|
||||
DECORM_CLOSE = (1<<5),
|
||||
DECORM_MENU = (1<<6),
|
||||
DECORM_STICKY = (1<<7),
|
||||
DECORM_SHADE = (1<<8),
|
||||
DECORM_TAB = (1<<9),
|
||||
DECORM_ENABLED = (1<<10),
|
||||
DECORM_LAST = (1<<11) // useful for getting "All"
|
||||
};
|
||||
|
||||
enum Decoration {
|
||||
DECOR_NONE = 0,
|
||||
DECOR_NORMAL = DECORM_LAST - 1,
|
||||
DECOR_TINY = DECORM_TITLEBAR|DECORM_ICONIFY|DECORM_MENU|DECORM_TAB,
|
||||
DECOR_TOOL = DECORM_TITLEBAR|DECORM_MENU,
|
||||
DECOR_BORDER = DECORM_BORDER|DECORM_MENU,
|
||||
DECOR_TAB = DECORM_BORDER|DECORM_MENU|DECORM_TAB
|
||||
};
|
||||
|
||||
WindowState():
|
||||
size_hints(),
|
||||
deco_mask(DECOR_NORMAL),
|
||||
focused(false),
|
||||
shaded(false), fullscreen(false), maximized(0),
|
||||
x(0), y(0), width(1), height(1) { }
|
||||
|
||||
void saveGeometry(int x, int y, unsigned int width, unsigned int height);
|
||||
|
||||
bool useBorder() const;
|
||||
bool useHandle() const;
|
||||
bool useTabs() const;
|
||||
bool useTitlebar() const;
|
||||
|
||||
static int getDecoMaskFromString(const std::string &str);
|
||||
|
||||
SizeHints size_hints;
|
||||
unsigned int deco_mask;
|
||||
bool focused, shaded, fullscreen;
|
||||
int maximized;
|
||||
int x, y;
|
||||
unsigned int width, height;
|
||||
};
|
||||
|
||||
#endif // WINDOWSTATE_HH
|
Loading…
Reference in a new issue