sync with blackbox-cvs

This commit is contained in:
Dana Jansens 2002-06-21 01:06:29 +00:00
parent 8941da8e41
commit 1766453ca2
8 changed files with 180 additions and 93 deletions

View file

@ -411,45 +411,57 @@ ScreenInfo::ScreenInfo(BaseDisplay *d, unsigned int num) {
screen_number = num; screen_number = num;
root_window = RootWindow(basedisplay->getXDisplay(), screen_number); root_window = RootWindow(basedisplay->getXDisplay(), screen_number);
depth = DefaultDepth(basedisplay->getXDisplay(), screen_number);
rect.setSize(WidthOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(), rect.setSize(WidthOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(),
screen_number)), screen_number)),
HeightOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(), HeightOfScreen(ScreenOfDisplay(basedisplay->getXDisplay(),
screen_number))); 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 depth = DefaultDepth(basedisplay->getXDisplay(), screen_number);
// default visual for the screen 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; XVisualInfo vinfo_template, *vinfo_return;
int vinfo_nitems; int vinfo_nitems;
int best = -1;
vinfo_template.screen = screen_number; vinfo_template.screen = screen_number;
vinfo_template.c_class = TrueColor; vinfo_template.c_class = TrueColor;
visual = (Visual *) 0;
vinfo_return = XGetVisualInfo(basedisplay->getXDisplay(), vinfo_return = XGetVisualInfo(basedisplay->getXDisplay(),
VisualScreenMask | VisualClassMask, VisualScreenMask | VisualClassMask,
&vinfo_template, &vinfo_nitems); &vinfo_template, &vinfo_nitems);
if (vinfo_return && vinfo_nitems > 0) { if (vinfo_return) {
for (int i = 0; i < vinfo_nitems; i++) { int max_depth = 1;
if (depth < (vinfo_return + i)->depth) { for (int i = 0; i < vinfo_nitems; ++i) {
depth = (vinfo_return + i)->depth; if (vinfo_return[i].depth > max_depth) {
visual = (vinfo_return + i)->visual; 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); 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 // get the default display string and strip the screen number
string default_string = DisplayString(basedisplay->getXDisplay()); string default_string = DisplayString(basedisplay->getXDisplay());
const string::size_type pos = default_string.rfind("."); const string::size_type pos = default_string.rfind(".");

View file

@ -201,14 +201,11 @@ Basemenu::~Basemenu(void) {
} }
BasemenuItem::~BasemenuItem(void) {}
BasemenuItem *Basemenu::find(int index) { 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 (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, 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); BasemenuItem *item = find(index);
if (! item) return; if (! item) return;

View file

@ -163,8 +163,6 @@ public:
f(0), enabled(1), f(0), enabled(1),
selected(0) {} selected(0) {}
~BasemenuItem(void);
inline const char *exec(void) const { return e.c_str(); } inline const char *exec(void) const { return e.c_str(); }
inline const char *label(void) const { return l.c_str(); } inline const char *label(void) const { return l.c_str(); }
inline int function(void) const { return f; } inline int function(void) const { return f; }

View file

@ -245,6 +245,8 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) {
workspacemenu->setItemSelected(2, True); workspacemenu->setItemSelected(2, True);
removeWorkspaceNames(); // do not need them any longer
toolbar = new Toolbar(this); toolbar = new Toolbar(this);
slit = new Slit(this); slit = new Slit(this);
@ -593,7 +595,6 @@ void BScreen::load_rc(void) {
else else
resource.col_direction = TopBottom; resource.col_direction = TopBottom;
removeWorkspaceNames();
if (config->getValue(screenstr + "workspaceNames", s)) { if (config->getValue(screenstr + "workspaceNames", s)) {
string::const_iterator it = s.begin(), end = s.end(); string::const_iterator it = s.begin(), end = s.end();
while(1) { while(1) {
@ -1060,10 +1061,6 @@ void BScreen::changeWorkspaceID(unsigned int id) {
if (! current_workspace) return; if (! current_workspace) return;
if (id != current_workspace->getID()) { if (id != current_workspace->getID()) {
current_workspace->hideAll();
workspacemenu->setItemSelected(current_workspace->getID() + 2, False);
BlackboxWindow *focused = blackbox->getFocusedWindow(); BlackboxWindow *focused = blackbox->getFocusedWindow();
if (focused && focused->getScreen() == this && ! focused->isStuck()) { if (focused && focused->getScreen() == this && ! focused->isStuck()) {
if (focused->getWorkspaceNumber() != current_workspace->getID()) { if (focused->getWorkspaceNumber() != current_workspace->getID()) {
@ -1072,8 +1069,15 @@ void BScreen::changeWorkspaceID(unsigned int id) {
abort(); abort();
} }
current_workspace->setLastFocusedWindow(focused); 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); current_workspace = getWorkspace(id);
@ -1229,7 +1233,7 @@ void BScreen::updateNetizenConfigNotify(XEvent *e) {
void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) { 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 *session_stack = new
Window[(num + workspacesList.size() + rootmenuList.size() + 13)]; Window[(num + workspacesList.size() + rootmenuList.size() + 13)];
unsigned int i = 0, k = num; unsigned int i = 0, k = num;

View file

@ -433,25 +433,29 @@ void Slit::updateStrut(void) {
strut.top = strut.bottom = strut.left = strut.right = 0; strut.top = strut.bottom = strut.left = strut.right = 0;
if (! clientList.empty()) { 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) { switch (direction) {
case Vertical: case Vertical:
switch (placement) { switch (placement) {
case TopCenter: case TopCenter:
strut.top = getY() + getExposedHeight() + strut.top = getExposedHeight() + border_width;
(screen->getBorderWidth() * 2);
break; break;
case BottomCenter: case BottomCenter:
strut.bottom = screen->getHeight() - getY(); strut.bottom = getExposedHeight() + border_width;
break; break;
case TopLeft: case TopLeft:
case CenterLeft: case CenterLeft:
case BottomLeft: case BottomLeft:
strut.left = getExposedWidth() + (screen->getBorderWidth() * 2); strut.left = getExposedWidth() + border_width;
break; break;
case TopRight: case TopRight:
case CenterRight: case CenterRight:
case BottomRight: case BottomRight:
strut.right = getExposedWidth() + (screen->getBorderWidth() * 2); strut.right = getExposedWidth() + border_width;
break; break;
} }
break; break;
@ -460,19 +464,18 @@ void Slit::updateStrut(void) {
case TopCenter: case TopCenter:
case TopLeft: case TopLeft:
case TopRight: case TopRight:
strut.top = getY() + getExposedHeight() + strut.top = getExposedHeight() + border_width;
(screen->getBorderWidth() * 2);
break; break;
case BottomCenter: case BottomCenter:
case BottomLeft: case BottomLeft:
case BottomRight: case BottomRight:
strut.bottom = screen->getHeight() - getY(); strut.bottom = getExposedHeight() + border_width;
break; break;
case CenterLeft: case CenterLeft:
strut.left = getExposedWidth() + (screen->getBorderWidth() * 2); strut.left = getExposedWidth() + border_width;
break; break;
case CenterRight: case CenterRight:
strut.right = getExposedWidth() + (screen->getBorderWidth() * 2); strut.right = getExposedWidth() + border_width;
break; break;
} }
break; break;

View file

@ -528,15 +528,20 @@ void Toolbar::updateStrut(void) {
// left and right are always 0 // left and right are always 0
strut.top = strut.bottom = 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()) { if (! screen->doHideToolbar()) {
switch(placement) { switch(placement) {
case TopLeft: case TopLeft:
case TopCenter: case TopCenter:
case TopRight: case TopRight:
strut.top = getExposedHeight() + (screen->getBorderWidth() * 2); strut.top = getExposedHeight() + border_width;
break; break;
default: default:
strut.bottom = getExposedHeight() + (screen->getBorderWidth() * 2); strut.bottom = getExposedHeight() + border_width;
} }
} }

View file

@ -68,9 +68,11 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
fprintf(stderr, "BlackboxWindow::BlackboxWindow(): creating 0x%lx\n", w); fprintf(stderr, "BlackboxWindow::BlackboxWindow(): creating 0x%lx\n", w);
#endif // DEBUG #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 set timer to zero... it is initialized properly later, so we check
// fully constructed if timer is zero... if timer is zero in the destructor, and assume that the window is not
fully constructed if timer is zero...
*/
timer = 0; timer = 0;
blackbox = b; blackbox = b;
client.window = w; 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.wm_hint_flags = client.normal_hint_flags = 0;
client.transient_for = 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 get the initial size and location of client window (relative to the
// window's gravity to find the window's initial position. _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.rect.setRect(wattrib.x, wattrib.y, wattrib.width, wattrib.height);
client.old_bw = wattrib.border_width; client.old_bw = wattrib.border_width;
@ -254,15 +258,48 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
frame.rect.width(), frame.rect.height()); 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) { if (flags.shaded) {
flags.shaded = False; flags.shaded = False;
shade(); 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)) { if (flags.maximized && (functions & Func_Maximize)) {
remaximize(); 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); setFocusFlag(False);
} }
@ -1309,6 +1346,16 @@ void BlackboxWindow::configureShape(void) {
bool BlackboxWindow::setInputFocus(void) { bool BlackboxWindow::setInputFocus(void) {
if (flags.focused) return True; 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())) { if (! client.rect.intersects(screen->getRect())) {
// client is outside the screen, move it to the center // client is outside the screen, move it to the center
configure((screen->getWidth() - frame.rect.width()) / 2, configure((screen->getWidth() - frame.rect.width()) / 2,
@ -1406,7 +1453,8 @@ void BlackboxWindow::iconify(void) {
void BlackboxWindow::show(void) { void BlackboxWindow::show(void) {
setState(NormalState); current_state = (flags.shaded) ? IconicState : NormalState;
setState(current_state);
XMapWindow(blackbox->getXDisplay(), client.window); XMapWindow(blackbox->getXDisplay(), client.window);
XMapSubwindows(blackbox->getXDisplay(), frame.window); XMapSubwindows(blackbox->getXDisplay(), frame.window);
@ -1463,10 +1511,12 @@ void BlackboxWindow::withdraw(void) {
XUnmapWindow(blackbox->getXDisplay(), frame.window); XUnmapWindow(blackbox->getXDisplay(), frame.window);
XGrabServer(blackbox->getXDisplay()); XGrabServer(blackbox->getXDisplay());
XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask); XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask);
XUnmapWindow(blackbox->getXDisplay(), client.window); XUnmapWindow(blackbox->getXDisplay(), client.window);
XSelectInput(blackbox->getXDisplay(), client.window, XSelectInput(blackbox->getXDisplay(), client.window,
PropertyChangeMask | FocusChangeMask | StructureNotifyMask); PropertyChangeMask | FocusChangeMask | StructureNotifyMask);
XUngrabServer(blackbox->getXDisplay()); XUngrabServer(blackbox->getXDisplay());
if (windowmenu) windowmenu->hide(); if (windowmenu) windowmenu->hide();
@ -1631,6 +1681,10 @@ void BlackboxWindow::stick(void) {
void BlackboxWindow::setFocusFlag(bool focus) { void BlackboxWindow::setFocusFlag(bool focus) {
// only focus a window if it is visible
if (focus && !flags.visible)
return;
flags.focused = focus; flags.focused = focus;
if (decorations & Decor_Titlebar) { if (decorations & Decor_Titlebar) {
@ -1785,8 +1839,6 @@ bool BlackboxWindow::getState(void) {
void BlackboxWindow::restoreAttributes(void) { void BlackboxWindow::restoreAttributes(void) {
if (! getState()) current_state = NormalState;
Atom atom_return; Atom atom_return;
int foo; int foo;
unsigned long ulfoo, nitems; unsigned long ulfoo, nitems;
@ -1801,36 +1853,42 @@ void BlackboxWindow::restoreAttributes(void) {
if (ret != Success || ! net || nitems != PropBlackboxAttributesElements) if (ret != Success || ! net || nitems != PropBlackboxAttributesElements)
return; return;
if (net->flags & AttribShaded && if (net->flags & AttribShaded && net->attrib & AttribShaded) {
net->attrib & AttribShaded) {
int save_state =
((current_state == IconicState) ? NormalState : current_state);
flags.shaded = False; flags.shaded = False;
shade(); 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()) && if ((net->workspace != screen->getCurrentWorkspaceID()) &&
(net->workspace < screen->getWorkspaceCount())) { (net->workspace < screen->getWorkspaceCount())) {
screen->reassociateWindow(this, net->workspace, True); 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; if (current_state == NormalState) current_state = WithdrawnState;
} else if (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; current_state = NormalState;
} }
if (net->flags & AttribOmnipresent && if (net->flags & AttribOmnipresent && net->attrib & AttribOmnipresent) {
net->attrib & AttribOmnipresent) {
flags.stuck = False; flags.stuck = False;
stick(); 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) || if (net->flags & AttribMaxHoriz || net->flags & AttribMaxVert) {
(net->flags & AttribMaxVert)) {
int x = net->premax_x, y = net->premax_y; int x = net->premax_x, y = net->premax_y;
unsigned int w = net->premax_w, h = net->premax_h; unsigned int w = net->premax_w, h = net->premax_h;
flags.maximized = 0; flags.maximized = 0;
@ -1852,7 +1910,8 @@ void BlackboxWindow::restoreAttributes(void) {
blackbox_attrib.premax_h = h; 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); XFree((void *) net);
} }
@ -2091,17 +2150,6 @@ void BlackboxWindow::mapRequestEvent(XMapRequestEvent *re) {
client.window); client.window);
#endif // DEBUG #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) { switch (current_state) {
case IconicState: case IconicState:
iconify(); iconify();

View file

@ -97,18 +97,39 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) {
stackingList.remove(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; BlackboxWindow *newfocus = 0;
if (w->isTransient()) if (w->isTransient())
newfocus = w->getTransientFor(); newfocus = w->getTransientFor();
if (! newfocus && ! stackingList.empty()) if (! newfocus && ! stackingList.empty())
newfocus = stackingList.front(); newfocus = stackingList.front();
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()) if (! newfocus || ! newfocus->setInputFocus())
screen->getBlackbox()->setFocusedWindow(0); 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 (lastfocus == w) /*
lastfocus = (BlackboxWindow *) 0; 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); windowList.remove(w);
clientmenu->remove(w->getWindowNumber()); clientmenu->remove(w->getWindowNumber());