make FbWinFrame and FluxboxWindow share a WindowState object

This commit is contained in:
Mark Tiefenbruck 2008-08-27 16:29:35 -04:00
parent 84c87a86f9
commit a2ec0c9bdd
8 changed files with 107 additions and 135 deletions

View file

@ -43,14 +43,12 @@ using std::string;
FbWinFrame::FbWinFrame(BScreen &screen,
FocusableTheme<FbWinFrameTheme> &theme,
FbTk::ImageControl &imgctrl,
FbTk::XLayer &layer,
int x, int y,
unsigned int width, unsigned int height):
FbTk::XLayer &layer, WindowState &state):
m_screen(screen),
m_theme(theme),
m_imagectrl(imgctrl),
m_window(theme->screenNum(), x, y, width, height,
m_imagectrl(screen.imageControl()),
m_state(state),
m_window(theme->screenNum(), state.x, state.y, state.width, state.height,
ButtonPressMask | ButtonReleaseMask |
ButtonMotionMask | EnterWindowMask |
LeaveWindowMask, true),
@ -189,19 +187,6 @@ void FbWinFrame::show() {
m_window.show();
}
/**
Toggle shade state, and resize window
*/
void FbWinFrame::shade() {
if (!(m_state.deco_mask & WindowState::DECORM_TITLEBAR))
return;
// toggle shade
m_state.shaded = !m_state.shaded;
applyState();
}
void FbWinFrame::move(int x, int y) {
moveResize(x, y, 0, 0, true, false);
}
@ -519,22 +504,6 @@ void FbWinFrame::setFocus(bool newvalue) {
clearAll();
}
void FbWinFrame::setFullscreen(bool newvalue) {
if (newvalue == m_state.fullscreen)
return;
m_state.fullscreen = newvalue;
applyState();
}
void FbWinFrame::setMaximized(int value) {
if (value == m_state.maximized)
return;
m_state.maximized = value;
applyState();
}
void FbWinFrame::applyState() {
applyDecorations();
@ -542,7 +511,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 & WindowState::MAX_VERT) {
if (m_state.isMaximizedVert()) {
new_y = m_screen.maxTop(head);
new_h = m_screen.maxBottom(head) - new_y - 2*window().borderWidth();
if (!m_screen.getMaxOverTabs()) {
@ -550,7 +519,7 @@ void FbWinFrame::applyState() {
new_h -= heightOffset();
}
}
if (m_state.maximized & WindowState::MAX_HORZ) {
if (m_state.isMaximizedHorz()) {
new_x = m_screen.maxLeft(head);
new_w = m_screen.maxRight(head) - new_x - 2*window().borderWidth();
if (!m_screen.getMaxOverTabs()) {

View file

@ -72,10 +72,7 @@ public:
/// create a top level window
FbWinFrame(BScreen &screen, FocusableTheme<FbWinFrameTheme> &theme,
FbTk::ImageControl &imgctrl,
FbTk::XLayer &layer,
int x, int y,
unsigned int width, unsigned int height);
FbTk::XLayer &layer, WindowState &state);
/* /// create a frame window inside another FbWindow, NOT IMPLEMENTED!
FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl,
@ -89,8 +86,7 @@ public:
void hide();
void show();
bool isVisible() const { return m_visible; }
/// shade frame (ie resize to titlebar size)
void shade();
void move(int x, int y);
void resize(unsigned int width, unsigned int height);
/// resize client to specified size and resize frame to it
@ -117,8 +113,6 @@ public:
/// set focus/unfocus style
void setFocus(bool newvalue);
void setFullscreen(bool value);
void setMaximized(int value);
void setFocusTitle(const std::string &str) { m_label.setText(str); }
bool setTabMode(TabMode tabmode);
@ -201,11 +195,6 @@ public:
unsigned int width() const { return m_window.width(); }
unsigned int height() const { return m_window.height(); }
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;
int yOffset() const;
@ -234,7 +223,6 @@ public:
const FbTk::FbWindow &gripRight() const { return m_grip_right; }
FbTk::FbWindow &gripRight() { return m_grip_right; }
bool focused() const { return m_state.focused; }
bool isShaded() const { return m_state.shaded; }
FocusableTheme<FbWinFrameTheme> &theme() const { return m_theme; }
/// @return titlebar height
unsigned int titlebarHeight() const { return (m_use_titlebar?m_titlebar.height()+m_titlebar.borderWidth():0); }
@ -311,6 +299,8 @@ private:
FocusableTheme<FbWinFrameTheme> &m_theme; ///< theme to be used
FbTk::ImageControl &m_imagectrl; ///< Image control for rendering
WindowState &m_state;
/**
@name windows
*/
@ -380,7 +370,6 @@ private:
TabMode m_tabmode;
unsigned int m_active_orig_client_bw;
WindowState m_state;
bool m_need_render;
int m_button_size; ///< size for all titlebar buttons

View file

@ -1115,15 +1115,15 @@ void Remember::rememberAttrib(WinClient &winclient, Attribute attrib) {
app->rememberHead(win->screen().getHead(win->fbWindow()));
break;
case REM_DIMENSIONS:
app->rememberDimensions(win->frame().normalWidth(),
win->frame().normalHeight());
app->rememberDimensions(win->normalWidth(),
win->normalHeight());
break;
case REM_POSITION: {
int head = win->screen().getHead(win->fbWindow());
int head_x = win->screen().maxLeft(head);
int head_y = win->screen().maxTop(head);
app->rememberPosition(win->frame().normalX() - head_x,
win->frame().normalY() - head_y);
app->rememberPosition(win->normalX() - head_x,
win->normalY() - head_y);
break;
}
case REM_FOCUSHIDDENSTATE:

View file

@ -115,8 +115,8 @@ bool ScreenPlacement::placeWindow(const FluxboxWindow &win, int head,
int win_w = win.width() + win.fbWindow().borderWidth()*2 + win.widthOffset(),
win_h = win.height() + win.fbWindow().borderWidth()*2 + win.heightOffset();
int win_w = win.normalWidth() + win.fbWindow().borderWidth()*2 + win.widthOffset(),
win_h = win.normalHeight() + win.fbWindow().borderWidth()*2 + win.heightOffset();
// make sure the window is inside our screen(head) area
if (place_x + win_w - win.xOffset() > head_right)

View file

@ -269,9 +269,8 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbTk::XLayer &layer):
m_layersig(*this),
m_workspacesig(*this),
m_creation_time(0),
moving(false), resizing(false), shaded(false), iconic(false),
stuck(false), m_initialized(false), fullscreen(false),
maximized(WindowState::MAX_NONE),
moving(false), resizing(false), iconic(false), stuck(false),
m_initialized(false),
m_attaching_tab(0),
display(FbTk::App::instance()->display()),
m_button_grab_x(0), m_button_grab_y(0),
@ -292,8 +291,7 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbTk::XLayer &layer):
screen().unfocusedWinButtonTheme()),
m_theme(*this, screen().focusedWinFrameTheme(),
screen().unfocusedWinFrameTheme()),
m_frame(client.screen(), m_theme, client.screen().imageControl(), layer,
0, 0, 100, 100),
m_frame(client.screen(), m_theme, layer, m_state),
m_placed(false),
m_layernum(layer.getLayerNum()),
m_old_layernum(0),
@ -509,11 +507,11 @@ void FluxboxWindow::init() {
unsigned int real_width = frame().width(), real_height = frame().height();
frame().applySizeHints(real_width, real_height);
screen().getWorkspace(m_workspace_number)->addWindow(*this);
if (m_placed)
moveResize(frame().x(), frame().y(), real_width, real_height);
if (!m_placed) placeWindow(getOnHead());
screen().getWorkspace(m_workspace_number)->addWindow(*this);
else
placeWindow(getOnHead());
setFocusFlag(false); // update graphics before mapping
@ -522,8 +520,8 @@ void FluxboxWindow::init() {
stick();
}
if (shaded) { // start shaded
shaded = false;
if (m_state.shaded) { // start shaded
m_state.shaded = false;
shade();
}
@ -542,14 +540,14 @@ void FluxboxWindow::init() {
}
}
if (fullscreen) {
fullscreen = false;
if (m_state.fullscreen) {
m_state.fullscreen = false;
setFullscreen(true);
}
if (maximized) {
int tmp = maximized;
maximized = WindowState::MAX_NONE;
if (m_state.maximized) {
int tmp = m_state.maximized;
m_state.maximized = WindowState::MAX_NONE;
setMaximizedState(tmp);
}
@ -1226,7 +1224,7 @@ void FluxboxWindow::moveResizeForClient(int new_x, int new_y,
m_placed = true;
frame().moveResizeForClient(new_x, new_y, new_width, new_height, gravity, client_bw);
setFocusFlag(m_focused);
shaded = false;
m_state.shaded = false;
sendConfigureNotify();
if (!moving) {
@ -1449,15 +1447,15 @@ void FluxboxWindow::setFullscreen(bool flag) {
if (!m_initialized) {
// this will interfere with window placement, so we delay it
fullscreen = flag;
m_state.fullscreen = flag;
return;
}
if (flag && !isFullscreen()) {
m_old_layernum = layerNum();
fullscreen = true;
frame().setFullscreen(true);
m_state.fullscreen = true;
frame().applyState();
setFullscreenLayer(); // calls stateSig().notify()
if (!isFocused())
@ -1465,8 +1463,8 @@ void FluxboxWindow::setFullscreen(bool flag) {
} else if (!flag && isFullscreen()) {
fullscreen = false;
frame().setFullscreen(false);
m_state.fullscreen = false;
frame().applyState();
moveToLayer(m_old_layernum);
stateSig().notify();
@ -1491,45 +1489,26 @@ void FluxboxWindow::setFullscreenLayer() {
Maximize window both horizontal and vertical
*/
void FluxboxWindow::maximize(int type) {
// nothing to do
if (type == WindowState::MAX_NONE)
return;
int new_max = maximized;
// toggle maximize vertically?
// 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 != WindowState::MAX_HORZ &&
(type != WindowState::MAX_FULL || maximized != WindowState::MAX_VERT))
new_max ^= WindowState::MAX_VERT;
// maximize horizontally?
if (type != WindowState::MAX_VERT &&
(type != WindowState::MAX_FULL || maximized != WindowState::MAX_HORZ))
new_max ^= WindowState::MAX_HORZ;
int new_max = m_state.queryToggleMaximized(type);
setMaximizedState(new_max);
}
void FluxboxWindow::setMaximizedState(int type) {
if (!m_initialized || type == maximized) {
if (!m_initialized || type == m_state.maximized) {
// this will interfere with window placement, so we delay it
maximized = type;
m_state.maximized = type;
return;
}
if (isResizing())
stopResizing();
maximized = type;
frame().setMaximized(type);
m_state.maximized = type;
frame().applyState();
// notify when struts change, so we can resize accordingly
if (maximized)
if (m_state.maximized)
screen().workspaceAreaSig().attach(this);
else
screen().workspaceAreaSig().detach(this);
@ -1590,27 +1569,27 @@ void FluxboxWindow::shade() {
if (!decorations.titlebar)
return;
// we're toggling, so if they're equal now, we need to change it
if (m_initialized && m_frame.isShaded() == shaded)
frame().shade();
m_state.shaded = !m_state.shaded;
if (!m_initialized)
return;
shaded = !shaded;
frame().applyState();
stateSig().notify();
// TODO: this should set IconicState, but then we can't focus the window
}
void FluxboxWindow::shadeOn() {
if (!shaded)
if (!m_state.shaded)
shade();
}
void FluxboxWindow::shadeOff() {
if (shaded)
if (m_state.shaded)
shade();
}
void FluxboxWindow::setShaded(bool val) {
if (val != shaded)
if (val != m_state.shaded)
shade();
}
@ -1789,10 +1768,10 @@ void FluxboxWindow::setFocusFlag(bool focus) {
// if we're fullscreen and another window gains focus on the same head,
// then we need to let the user see it
if (fullscreen && !focus)
if (m_state.fullscreen && !focus)
screen().focusedWindowSig().attach(this);
if (fullscreen && focus) {
if (m_state.fullscreen && focus) {
moveToLayer(::Layer::ABOVE_DOCK);
screen().focusedWindowSig().detach(this);
}
@ -3149,8 +3128,10 @@ void FluxboxWindow::startResizing(int x, int y, ReferenceCorner dir) {
m_resize_corner = dir;
resizing = true;
maximized = WindowState::MAX_NONE;
frame().setMaximized(maximized);
m_state.maximized = WindowState::MAX_NONE;
m_state.saveGeometry(frame().x(), frame().y(),
frame().width(), frame().height());
frame().applyState();
const Cursor& cursor = (m_resize_corner == LEFTTOP) ? frame().theme()->upperLeftAngleCursor() :
(m_resize_corner == RIGHTTOP) ? frame().theme()->upperRightAngleCursor() :
@ -3814,11 +3795,12 @@ void FluxboxWindow::setOnHead(int head) {
}
void FluxboxWindow::placeWindow(int head) {
int place_x, place_y;
int new_x, new_y;
// we ignore the return value,
// the screen placement strategy is guaranteed to succeed.
screen().placementStrategy().placeWindow(*this, head, place_x, place_y);
move(place_x, place_y);
screen().placementStrategy().placeWindow(*this, head, new_x, new_y);
m_state.saveGeometry(new_x, new_y, frame().width(), frame().height(), true);
move(new_x, new_y);
}
void FluxboxWindow::setWindowType(Focusable::WindowType type) {

View file

@ -371,12 +371,12 @@ public:
bool isManaged() const { return m_initialized; }
bool isVisible() const;
bool isIconic() const { return iconic; }
bool isShaded() const { return shaded; }
bool isFullscreen() const { return fullscreen; }
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 isShaded() const { return m_state.shaded; }
bool isFullscreen() const { return m_state.fullscreen; }
bool isMaximized() const { return m_state.isMaximized(); }
bool isMaximizedVert() const { return m_state.isMaximizedVert(); }
bool isMaximizedHorz() const { return m_state.isMaximizedHorz(); }
int maximizedState() const { return m_state.maximized; }
bool isIconifiable() const { return functions.iconify; }
bool isMaximizable() const { return functions.maximize; }
bool isResizable() const { return functions.resize; }
@ -425,6 +425,11 @@ public:
unsigned int width() const { return frame().width(); }
unsigned int height() const { return frame().height(); }
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; }
int xOffset() const { return frame().xOffset(); }
int yOffset() const { return frame().yOffset(); }
int widthOffset() const { return frame().widthOffset(); }
@ -526,10 +531,7 @@ private:
time_t m_creation_time;
// Window states
bool moving, resizing, shaded, iconic,
stuck, m_initialized, fullscreen;
int maximized;
bool moving, resizing, iconic, stuck, m_initialized;
WinClient *m_attaching_tab;
@ -579,7 +581,9 @@ private:
FocusableTheme<WinButtonTheme> m_button_theme;
FocusableTheme<FbWinFrameTheme> m_theme;
FbWinFrame m_frame; ///< the actuall window frame
WindowState m_state;
FbWinFrame m_frame; ///< the actual window frame
bool m_placed; ///< determine whether or not we should place the window

View file

@ -43,21 +43,41 @@ bool WindowState::useTitlebar() const {
}
void WindowState::saveGeometry(int new_x, int new_y,
unsigned int new_w, unsigned int new_h) {
if (fullscreen || maximized == MAX_FULL)
unsigned int new_w, unsigned int new_h,
bool force) {
if ((fullscreen || maximized == MAX_FULL) && !force)
return;
if (!(maximized & MAX_HORZ)) {
if (!(maximized & MAX_HORZ) || force) {
x = new_x;
width = new_w;
}
if (!(maximized & MAX_VERT)) {
if (!(maximized & MAX_VERT) || force) {
y = new_y;
if (!shaded)
if (!shaded || force)
height = new_h;
}
}
int WindowState::queryToggleMaximized(int type) const {
if (type == MAX_NONE)
return maximized;
int new_max = maximized;
// toggle maximize vertically?
// when _don't_ we want to toggle?
// - type is horizontal maximize, or
// - type is full and we are not maximized horz but already vertically
if (type != MAX_HORZ && (type != MAX_FULL || maximized != MAX_VERT))
new_max ^= MAX_VERT;
// maximize horizontally?
if (type != MAX_VERT && (type != MAX_FULL || maximized != MAX_HORZ))
new_max ^= MAX_HORZ;
return new_max;
}
int WindowState::getDecoMaskFromString(const std::string &str_label) {
std::string label = FbTk::StringUtil::toLower(str_label);
if (label == "none")

View file

@ -100,13 +100,21 @@ public:
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);
void saveGeometry(int x, int y, unsigned int width, unsigned int height,
bool force = false);
// returns what the state should be set to, without actually setting it
int queryToggleMaximized(int type) const;
bool useBorder() const;
bool useHandle() const;
bool useTabs() const;
bool useTitlebar() const;
bool isMaximized() const { return maximized == MAX_FULL; }
bool isMaximizedHorz() const { return (bool)(maximized & MAX_HORZ); }
bool isMaximizedVert() const { return (bool)(maximized & MAX_VERT); }
static int getDecoMaskFromString(const std::string &str);
SizeHints size_hints;