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;
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
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;
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;
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(".");

View file

@ -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;

View file

@ -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; }

View file

@ -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;

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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,10 +1511,12 @@ 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());
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();

View file

@ -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();
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 (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);
clientmenu->remove(w->getWindowNumber());