sync with blackbox-cvs
This commit is contained in:
parent
8941da8e41
commit
1766453ca2
8 changed files with 180 additions and 93 deletions
|
@ -411,45 +411,57 @@ ScreenInfo::ScreenInfo(BaseDisplay *d, unsigned int num) {
|
|||
screen_number = num;
|
||||
|
||||
root_window = RootWindow(basedisplay->getXDisplay(), screen_number);
|
||||
depth = DefaultDepth(basedisplay->getXDisplay(), screen_number);
|
||||
|
||||
rect.setSize(WidthOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(),
|
||||
screen_number)),
|
||||
HeightOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(),
|
||||
screen_number)));
|
||||
/*
|
||||
If the default depth is at least 15 we will use that,
|
||||
otherwise we try to find the largest TrueColor visual.
|
||||
Preference is given to 24 bit over larger depths if 24 bit is an option.
|
||||
*/
|
||||
|
||||
// search for a TrueColor Visual... if we can't find one... we will use the
|
||||
// default visual for the screen
|
||||
XVisualInfo vinfo_template, *vinfo_return;
|
||||
int vinfo_nitems;
|
||||
depth = DefaultDepth(basedisplay->getXDisplay(), screen_number);
|
||||
visual = DefaultVisual(basedisplay->getXDisplay(), screen_number);
|
||||
colormap = DefaultColormap(basedisplay->getXDisplay(), screen_number);
|
||||
|
||||
if (depth < 15) {
|
||||
// search for a TrueColor Visual... if we can't find one...
|
||||
// we will use the default visual for the screen
|
||||
XVisualInfo vinfo_template, *vinfo_return;
|
||||
int vinfo_nitems;
|
||||
int best = -1;
|
||||
|
||||
vinfo_template.screen = screen_number;
|
||||
vinfo_template.c_class = TrueColor;
|
||||
vinfo_template.screen = screen_number;
|
||||
vinfo_template.c_class = TrueColor;
|
||||
|
||||
visual = (Visual *) 0;
|
||||
|
||||
vinfo_return = XGetVisualInfo(basedisplay->getXDisplay(),
|
||||
VisualScreenMask | VisualClassMask,
|
||||
&vinfo_template, &vinfo_nitems);
|
||||
if (vinfo_return && vinfo_nitems > 0) {
|
||||
for (int i = 0; i < vinfo_nitems; i++) {
|
||||
if (depth < (vinfo_return + i)->depth) {
|
||||
depth = (vinfo_return + i)->depth;
|
||||
visual = (vinfo_return + i)->visual;
|
||||
vinfo_return = XGetVisualInfo(basedisplay->getXDisplay(),
|
||||
VisualScreenMask | VisualClassMask,
|
||||
&vinfo_template, &vinfo_nitems);
|
||||
if (vinfo_return) {
|
||||
int max_depth = 1;
|
||||
for (int i = 0; i < vinfo_nitems; ++i) {
|
||||
if (vinfo_return[i].depth > max_depth) {
|
||||
if (max_depth == 24 && vinfo_return[i].depth > 24)
|
||||
break; // prefer 24 bit over 32
|
||||
max_depth = vinfo_return[i].depth;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
if (max_depth < depth) best = -1;
|
||||
}
|
||||
|
||||
if (best != -1) {
|
||||
depth = vinfo_return[best].depth;
|
||||
visual = vinfo_return[best].visual;
|
||||
colormap = XCreateColormap(basedisplay->getXDisplay(), root_window,
|
||||
visual, AllocNone);
|
||||
}
|
||||
|
||||
XFree(vinfo_return);
|
||||
}
|
||||
|
||||
if (visual) {
|
||||
colormap = XCreateColormap(basedisplay->getXDisplay(), root_window,
|
||||
visual, AllocNone);
|
||||
} else {
|
||||
visual = DefaultVisual(basedisplay->getXDisplay(), screen_number);
|
||||
colormap = DefaultColormap(basedisplay->getXDisplay(), screen_number);
|
||||
}
|
||||
|
||||
// get the default display string and strip the screen number
|
||||
string default_string = DisplayString(basedisplay->getXDisplay());
|
||||
const string::size_type pos = default_string.rfind(".");
|
||||
|
|
|
@ -201,14 +201,11 @@ Basemenu::~Basemenu(void) {
|
|||
}
|
||||
|
||||
|
||||
BasemenuItem::~BasemenuItem(void) {}
|
||||
|
||||
|
||||
BasemenuItem *Basemenu::find(int index) {
|
||||
if (index < 0 || index > static_cast<signed>(menuitems.size()))
|
||||
if (index < 0 || index >= static_cast<signed>(menuitems.size()))
|
||||
return (BasemenuItem*) 0;
|
||||
|
||||
return *(menuitems.begin() + index);
|
||||
return menuitems[index];
|
||||
}
|
||||
|
||||
|
||||
|
@ -593,8 +590,7 @@ bool Basemenu::hasSubmenu(int index) {
|
|||
|
||||
|
||||
void Basemenu::drawItem(int index, bool highlight, bool clear,
|
||||
int x, int y, unsigned int w, unsigned int h)
|
||||
{
|
||||
int x, int y, unsigned int w, unsigned int h) {
|
||||
BasemenuItem *item = find(index);
|
||||
if (! item) return;
|
||||
|
||||
|
|
|
@ -163,8 +163,6 @@ public:
|
|||
f(0), enabled(1),
|
||||
selected(0) {}
|
||||
|
||||
~BasemenuItem(void);
|
||||
|
||||
inline const char *exec(void) const { return e.c_str(); }
|
||||
inline const char *label(void) const { return l.c_str(); }
|
||||
inline int function(void) const { return f; }
|
||||
|
|
|
@ -245,6 +245,8 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) {
|
|||
|
||||
workspacemenu->setItemSelected(2, True);
|
||||
|
||||
removeWorkspaceNames(); // do not need them any longer
|
||||
|
||||
toolbar = new Toolbar(this);
|
||||
|
||||
slit = new Slit(this);
|
||||
|
@ -593,7 +595,6 @@ void BScreen::load_rc(void) {
|
|||
else
|
||||
resource.col_direction = TopBottom;
|
||||
|
||||
removeWorkspaceNames();
|
||||
if (config->getValue(screenstr + "workspaceNames", s)) {
|
||||
string::const_iterator it = s.begin(), end = s.end();
|
||||
while(1) {
|
||||
|
@ -1060,10 +1061,6 @@ void BScreen::changeWorkspaceID(unsigned int id) {
|
|||
if (! current_workspace) return;
|
||||
|
||||
if (id != current_workspace->getID()) {
|
||||
current_workspace->hideAll();
|
||||
|
||||
workspacemenu->setItemSelected(current_workspace->getID() + 2, False);
|
||||
|
||||
BlackboxWindow *focused = blackbox->getFocusedWindow();
|
||||
if (focused && focused->getScreen() == this && ! focused->isStuck()) {
|
||||
if (focused->getWorkspaceNumber() != current_workspace->getID()) {
|
||||
|
@ -1072,8 +1069,15 @@ void BScreen::changeWorkspaceID(unsigned int id) {
|
|||
abort();
|
||||
}
|
||||
current_workspace->setLastFocusedWindow(focused);
|
||||
blackbox->setFocusedWindow((BlackboxWindow *) 0);
|
||||
} else {
|
||||
// if no window had focus, no need to store a last focus
|
||||
current_workspace->setLastFocusedWindow((BlackboxWindow *) 0);
|
||||
}
|
||||
// when we switch workspaces, unfocus whatever was focused
|
||||
blackbox->setFocusedWindow((BlackboxWindow *) 0);
|
||||
|
||||
current_workspace->hideAll();
|
||||
workspacemenu->setItemSelected(current_workspace->getID() + 2, False);
|
||||
|
||||
current_workspace = getWorkspace(id);
|
||||
|
||||
|
@ -1229,7 +1233,7 @@ void BScreen::updateNetizenConfigNotify(XEvent *e) {
|
|||
|
||||
|
||||
void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) {
|
||||
// XXX: why 13??
|
||||
// the 13 represents the number of blackbox windows such as menus
|
||||
Window *session_stack = new
|
||||
Window[(num + workspacesList.size() + rootmenuList.size() + 13)];
|
||||
unsigned int i = 0, k = num;
|
||||
|
|
23
src/Slit.cc
23
src/Slit.cc
|
@ -433,25 +433,29 @@ void Slit::updateStrut(void) {
|
|||
strut.top = strut.bottom = strut.left = strut.right = 0;
|
||||
|
||||
if (! clientList.empty()) {
|
||||
// when not hidden both borders are in use, when hidden only one is
|
||||
unsigned int border_width = screen->getBorderWidth();
|
||||
if (! do_auto_hide)
|
||||
border_width *= 2;
|
||||
|
||||
switch (direction) {
|
||||
case Vertical:
|
||||
switch (placement) {
|
||||
case TopCenter:
|
||||
strut.top = getY() + getExposedHeight() +
|
||||
(screen->getBorderWidth() * 2);
|
||||
strut.top = getExposedHeight() + border_width;
|
||||
break;
|
||||
case BottomCenter:
|
||||
strut.bottom = screen->getHeight() - getY();
|
||||
strut.bottom = getExposedHeight() + border_width;
|
||||
break;
|
||||
case TopLeft:
|
||||
case CenterLeft:
|
||||
case BottomLeft:
|
||||
strut.left = getExposedWidth() + (screen->getBorderWidth() * 2);
|
||||
strut.left = getExposedWidth() + border_width;
|
||||
break;
|
||||
case TopRight:
|
||||
case CenterRight:
|
||||
case BottomRight:
|
||||
strut.right = getExposedWidth() + (screen->getBorderWidth() * 2);
|
||||
strut.right = getExposedWidth() + border_width;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -460,19 +464,18 @@ void Slit::updateStrut(void) {
|
|||
case TopCenter:
|
||||
case TopLeft:
|
||||
case TopRight:
|
||||
strut.top = getY() + getExposedHeight() +
|
||||
(screen->getBorderWidth() * 2);
|
||||
strut.top = getExposedHeight() + border_width;
|
||||
break;
|
||||
case BottomCenter:
|
||||
case BottomLeft:
|
||||
case BottomRight:
|
||||
strut.bottom = screen->getHeight() - getY();
|
||||
strut.bottom = getExposedHeight() + border_width;
|
||||
break;
|
||||
case CenterLeft:
|
||||
strut.left = getExposedWidth() + (screen->getBorderWidth() * 2);
|
||||
strut.left = getExposedWidth() + border_width;
|
||||
break;
|
||||
case CenterRight:
|
||||
strut.right = getExposedWidth() + (screen->getBorderWidth() * 2);
|
||||
strut.right = getExposedWidth() + border_width;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -528,15 +528,20 @@ void Toolbar::updateStrut(void) {
|
|||
// left and right are always 0
|
||||
strut.top = strut.bottom = 0;
|
||||
|
||||
// when hidden only one border is visible
|
||||
unsigned int border_width = screen->getBorderWidth();
|
||||
if (! do_auto_hide)
|
||||
border_width *= 2;
|
||||
|
||||
if (! screen->doHideToolbar()) {
|
||||
switch(placement) {
|
||||
case TopLeft:
|
||||
case TopCenter:
|
||||
case TopRight:
|
||||
strut.top = getExposedHeight() + (screen->getBorderWidth() * 2);
|
||||
strut.top = getExposedHeight() + border_width;
|
||||
break;
|
||||
default:
|
||||
strut.bottom = getExposedHeight() + (screen->getBorderWidth() * 2);
|
||||
strut.bottom = getExposedHeight() + border_width;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
116
src/Window.cc
116
src/Window.cc
|
@ -68,9 +68,11 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
fprintf(stderr, "BlackboxWindow::BlackboxWindow(): creating 0x%lx\n", w);
|
||||
#endif // DEBUG
|
||||
|
||||
// set timer to zero... it is initialized properly later, so we check
|
||||
// if timer is zero in the destructor, and assume that the window is not
|
||||
// fully constructed if timer is zero...
|
||||
/*
|
||||
set timer to zero... it is initialized properly later, so we check
|
||||
if timer is zero in the destructor, and assume that the window is not
|
||||
fully constructed if timer is zero...
|
||||
*/
|
||||
timer = 0;
|
||||
blackbox = b;
|
||||
client.window = w;
|
||||
|
@ -139,9 +141,11 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
client.wm_hint_flags = client.normal_hint_flags = 0;
|
||||
client.transient_for = 0;
|
||||
|
||||
// get the initial size and location of client window (relative to the
|
||||
// _root window_). This position is the reference point used with the
|
||||
// window's gravity to find the window's initial position.
|
||||
/*
|
||||
get the initial size and location of client window (relative to the
|
||||
_root window_). This position is the reference point used with the
|
||||
window's gravity to find the window's initial position.
|
||||
*/
|
||||
client.rect.setRect(wattrib.x, wattrib.y, wattrib.width, wattrib.height);
|
||||
client.old_bw = wattrib.border_width;
|
||||
|
||||
|
@ -254,15 +258,48 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
frame.rect.width(), frame.rect.height());
|
||||
}
|
||||
|
||||
// preserve the window's initial state on first map, and its current state
|
||||
// across a restart
|
||||
if (! getState()) {
|
||||
if (client.wm_hint_flags & StateHint)
|
||||
current_state = client.initial_state;
|
||||
else
|
||||
current_state = NormalState;
|
||||
}
|
||||
|
||||
if (flags.shaded) {
|
||||
flags.shaded = False;
|
||||
shade();
|
||||
|
||||
/*
|
||||
Because the iconic'ness of shaded windows is lost, we need to set the
|
||||
state to NormalState so that shaded windows on other workspaces will not
|
||||
get shown on the first workspace.
|
||||
At this point in the life of a window, current_state should only be set
|
||||
to IconicState if the window was an *icon*, not if it was shaded.
|
||||
*/
|
||||
current_state = NormalState;
|
||||
}
|
||||
|
||||
if (flags.stuck) {
|
||||
flags.stuck = False;
|
||||
stick();
|
||||
}
|
||||
|
||||
if (flags.maximized && (functions & Func_Maximize)) {
|
||||
remaximize();
|
||||
}
|
||||
|
||||
/*
|
||||
When the window is mapped (and also when its attributes are restored), the
|
||||
current_state that was set here will be used.
|
||||
It is set to Normal if the window is to be mapped or it is set to Iconic
|
||||
if the window is to be iconified.
|
||||
*Note* that for sticky windows, the same rules apply here, they are in
|
||||
fact never set to Iconic since there is no way for us to tell if a sticky
|
||||
window was iconified previously.
|
||||
*/
|
||||
|
||||
setFocusFlag(False);
|
||||
}
|
||||
|
||||
|
@ -1309,6 +1346,16 @@ void BlackboxWindow::configureShape(void) {
|
|||
bool BlackboxWindow::setInputFocus(void) {
|
||||
if (flags.focused) return True;
|
||||
|
||||
assert(! flags.iconic);
|
||||
|
||||
// if the window is not visible, mark the window as wanting focus rather
|
||||
// than give it focus.
|
||||
if (! flags.visible) {
|
||||
Workspace *wkspc = screen->getWorkspace(blackbox_attrib.workspace);
|
||||
wkspc->setLastFocusedWindow(this);
|
||||
return True;
|
||||
}
|
||||
|
||||
if (! client.rect.intersects(screen->getRect())) {
|
||||
// client is outside the screen, move it to the center
|
||||
configure((screen->getWidth() - frame.rect.width()) / 2,
|
||||
|
@ -1406,7 +1453,8 @@ void BlackboxWindow::iconify(void) {
|
|||
|
||||
|
||||
void BlackboxWindow::show(void) {
|
||||
setState(NormalState);
|
||||
current_state = (flags.shaded) ? IconicState : NormalState;
|
||||
setState(current_state);
|
||||
|
||||
XMapWindow(blackbox->getXDisplay(), client.window);
|
||||
XMapSubwindows(blackbox->getXDisplay(), frame.window);
|
||||
|
@ -1463,11 +1511,13 @@ void BlackboxWindow::withdraw(void) {
|
|||
XUnmapWindow(blackbox->getXDisplay(), frame.window);
|
||||
|
||||
XGrabServer(blackbox->getXDisplay());
|
||||
|
||||
XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask);
|
||||
XUnmapWindow(blackbox->getXDisplay(), client.window);
|
||||
XSelectInput(blackbox->getXDisplay(), client.window,
|
||||
PropertyChangeMask | FocusChangeMask | StructureNotifyMask);
|
||||
XUngrabServer(blackbox->getXDisplay());
|
||||
|
||||
XUngrabServer(blackbox->getXDisplay());
|
||||
|
||||
if (windowmenu) windowmenu->hide();
|
||||
}
|
||||
|
@ -1631,6 +1681,10 @@ void BlackboxWindow::stick(void) {
|
|||
|
||||
|
||||
void BlackboxWindow::setFocusFlag(bool focus) {
|
||||
// only focus a window if it is visible
|
||||
if (focus && !flags.visible)
|
||||
return;
|
||||
|
||||
flags.focused = focus;
|
||||
|
||||
if (decorations & Decor_Titlebar) {
|
||||
|
@ -1785,8 +1839,6 @@ bool BlackboxWindow::getState(void) {
|
|||
|
||||
|
||||
void BlackboxWindow::restoreAttributes(void) {
|
||||
if (! getState()) current_state = NormalState;
|
||||
|
||||
Atom atom_return;
|
||||
int foo;
|
||||
unsigned long ulfoo, nitems;
|
||||
|
@ -1801,36 +1853,42 @@ void BlackboxWindow::restoreAttributes(void) {
|
|||
if (ret != Success || ! net || nitems != PropBlackboxAttributesElements)
|
||||
return;
|
||||
|
||||
if (net->flags & AttribShaded &&
|
||||
net->attrib & AttribShaded) {
|
||||
int save_state =
|
||||
((current_state == IconicState) ? NormalState : current_state);
|
||||
|
||||
if (net->flags & AttribShaded && net->attrib & AttribShaded) {
|
||||
flags.shaded = False;
|
||||
shade();
|
||||
|
||||
current_state = save_state;
|
||||
}
|
||||
/*
|
||||
Because the iconic'ness of shaded windows is lost, we need to set the
|
||||
state to NormalState so that shaded windows on other workspaces will not
|
||||
get shown on the first workspace.
|
||||
At this point in the life of a window, current_state should only be set
|
||||
to IconicState if the window was an *icon*, not if it was shaded.
|
||||
*/
|
||||
current_state = NormalState;
|
||||
}
|
||||
|
||||
if ((net->workspace != screen->getCurrentWorkspaceID()) &&
|
||||
(net->workspace < screen->getWorkspaceCount())) {
|
||||
screen->reassociateWindow(this, net->workspace, True);
|
||||
|
||||
// set to WithdrawnState so it will be mapped on the new workspace
|
||||
if (current_state == NormalState) current_state = WithdrawnState;
|
||||
} else if (current_state == WithdrawnState) {
|
||||
// the window is on this workspace and is Withdrawn, so it is waiting to
|
||||
// be mapped
|
||||
current_state = NormalState;
|
||||
}
|
||||
|
||||
if (net->flags & AttribOmnipresent &&
|
||||
net->attrib & AttribOmnipresent) {
|
||||
if (net->flags & AttribOmnipresent && net->attrib & AttribOmnipresent) {
|
||||
flags.stuck = False;
|
||||
stick();
|
||||
|
||||
current_state = NormalState;
|
||||
// if the window was on another workspace, it was going to be hidden. this
|
||||
// specifies that the window should be mapped since it is sticky.
|
||||
if (current_state == WithdrawnState) current_state = NormalState;
|
||||
}
|
||||
|
||||
if ((net->flags & AttribMaxHoriz) ||
|
||||
(net->flags & AttribMaxVert)) {
|
||||
if (net->flags & AttribMaxHoriz || net->flags & AttribMaxVert) {
|
||||
int x = net->premax_x, y = net->premax_y;
|
||||
unsigned int w = net->premax_w, h = net->premax_h;
|
||||
flags.maximized = 0;
|
||||
|
@ -1852,7 +1910,8 @@ void BlackboxWindow::restoreAttributes(void) {
|
|||
blackbox_attrib.premax_h = h;
|
||||
}
|
||||
|
||||
setState(current_state);
|
||||
// with the state set it will then be the map events job to read the window's
|
||||
// state and behave accordingly
|
||||
|
||||
XFree((void *) net);
|
||||
}
|
||||
|
@ -2091,17 +2150,6 @@ void BlackboxWindow::mapRequestEvent(XMapRequestEvent *re) {
|
|||
client.window);
|
||||
#endif // DEBUG
|
||||
|
||||
bool get_state_ret = getState();
|
||||
if (! (get_state_ret && blackbox->isStartup())) {
|
||||
if ((client.wm_hint_flags & StateHint) &&
|
||||
(! (current_state == NormalState || current_state == IconicState)))
|
||||
current_state = client.initial_state;
|
||||
else
|
||||
current_state = NormalState;
|
||||
} else if (flags.iconic) {
|
||||
current_state = NormalState;
|
||||
}
|
||||
|
||||
switch (current_state) {
|
||||
case IconicState:
|
||||
iconify();
|
||||
|
|
|
@ -97,18 +97,39 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) {
|
|||
|
||||
stackingList.remove(w);
|
||||
|
||||
if (w->isFocused() && ! screen->getBlackbox()->doShutdown()) {
|
||||
// pass focus to the next appropriate window
|
||||
if ((w->isFocused() || w == lastfocus) &&
|
||||
! screen->getBlackbox()->doShutdown()) {
|
||||
BlackboxWindow *newfocus = 0;
|
||||
if (w->isTransient())
|
||||
newfocus = w->getTransientFor();
|
||||
if (! newfocus && ! stackingList.empty())
|
||||
newfocus = stackingList.front();
|
||||
if (! newfocus || ! newfocus->setInputFocus())
|
||||
screen->getBlackbox()->setFocusedWindow(0);
|
||||
}
|
||||
|
||||
if (lastfocus == w)
|
||||
lastfocus = (BlackboxWindow *) 0;
|
||||
assert(newfocus != w); // this would be very wrong.
|
||||
|
||||
if (id == screen->getCurrentWorkspaceID()) {
|
||||
/*
|
||||
if the window is on the visible workspace, then try focus it, and fall
|
||||
back to the default focus target if the window won't focus.
|
||||
*/
|
||||
if (! newfocus || ! newfocus->setInputFocus())
|
||||
screen->getBlackbox()->setFocusedWindow(0);
|
||||
} else if (lastfocus == w) {
|
||||
/*
|
||||
If this workspace is not the current one do not assume that
|
||||
w == lastfocus. If a sticky window is removed on a workspace other
|
||||
than where it originated, it will fire the removeWindow on a
|
||||
non-visible workspace.
|
||||
*/
|
||||
|
||||
/*
|
||||
If the window isn't on the visible workspace, don't focus the new one,
|
||||
just mark it to be focused when the workspace comes into view.
|
||||
*/
|
||||
setLastFocusedWindow(newfocus);
|
||||
}
|
||||
}
|
||||
|
||||
windowList.remove(w);
|
||||
clientmenu->remove(w->getWindowNumber());
|
||||
|
|
Loading…
Reference in a new issue