sync with blackbox

This commit is contained in:
Dana Jansens 2002-08-07 00:24:58 +00:00
parent aa06c07dec
commit 72c56d793b
7 changed files with 224 additions and 211 deletions

View file

@ -1129,7 +1129,8 @@ void BScreen::removeIcon(BlackboxWindow *w) {
BlackboxWindow *BScreen::getIcon(unsigned int index) { BlackboxWindow *BScreen::getIcon(unsigned int index) {
if (index < iconList.size()) { if (index < iconList.size()) {
BlackboxWindowList::iterator it = iconList.begin(); BlackboxWindowList::iterator it = iconList.begin();
for (; index > 0; --index, ++it) ; /* increment to index */ while (index-- > 0) // increment to index
++it;
return *it; return *it;
} }
@ -1185,38 +1186,20 @@ unsigned int BScreen::removeLastWorkspace(void) {
void BScreen::changeWorkspaceID(unsigned int id) { void BScreen::changeWorkspaceID(unsigned int id) {
if (! current_workspace || id == current_workspace->getID()) return; if (! current_workspace || id == current_workspace->getID()) return;
BlackboxWindow *focused = blackbox->getFocusedWindow(); current_workspace->hide();
if (focused && focused->getScreen() == this) {
assert(focused->isStuck() ||
focused->getWorkspaceNumber() == current_workspace->getID());
current_workspace->setLastFocusedWindow(focused);
} 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); workspacemenu->setItemSelected(current_workspace->getID() + 2, False);
current_workspace = getWorkspace(id); current_workspace = getWorkspace(id);
current_workspace->show();
xatom->setValue(getRootWindow(), XAtom::net_current_desktop, xatom->setValue(getRootWindow(), XAtom::net_current_desktop,
XAtom::cardinal, id); XAtom::cardinal, id);
workspacemenu->setItemSelected(current_workspace->getID() + 2, True); workspacemenu->setItemSelected(current_workspace->getID() + 2, True);
toolbar->redrawWorkspaceLabel(True); toolbar->redrawWorkspaceLabel(True);
current_workspace->showAll();
if (resource.focus_last && current_workspace->getLastFocusedWindow()) {
XSync(blackbox->getXDisplay(), False);
current_workspace->getLastFocusedWindow()->setInputFocus();
}
updateNetizenCurrentWorkspace(); updateNetizenCurrentWorkspace();
} }
@ -1790,12 +1773,13 @@ void BScreen::InitMenu(void) {
static static
void string_within(char begin, char end, const char *input, size_t length, size_t string_within(char begin, char end,
char *output) { const char *input, size_t start_at, size_t length,
char *output) {
bool parse = False; bool parse = False;
size_t index = 0; size_t index = 0;
size_t i = start_at;
for (size_t i = 0; i < length; ++i) { for (; i < length; ++i) {
if (input[i] == begin) { if (input[i] == begin) {
parse = True; parse = True;
} else if (input[i] == end) { } else if (input[i] == end) {
@ -1810,6 +1794,8 @@ void string_within(char begin, char end, const char *input, size_t length,
output[index] = '\0'; output[index] = '\0';
else else
output[0] = '\0'; output[0] = '\0';
return i;
} }
@ -1832,7 +1818,7 @@ bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) {
unsigned int key = 0; unsigned int key = 0;
// get the keyword enclosed in []'s // get the keyword enclosed in []'s
string_within('[', ']', line, line_length, keyword); size_t pos = string_within('[', ']', line, 0, line_length, keyword);
if (keyword[0] == '\0') { // no keyword, no menu entry if (keyword[0] == '\0') { // no keyword, no menu entry
continue; continue;
@ -1845,10 +1831,10 @@ bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) {
} }
// get the label enclosed in ()'s // get the label enclosed in ()'s
string_within('(', ')', line, line_length, label); pos = string_within('(', ')', line, pos, line_length, label);
// get the command enclosed in {}'s // get the command enclosed in {}'s
string_within('{', '}', line, line_length, command); pos = string_within('{', '}', line, pos, line_length, command);
switch (key) { switch (key) {
case 311: // end case 311: // end

View file

@ -53,16 +53,14 @@ using std::string;
#include "i18n.hh" #include "i18n.hh"
#include "blackbox.hh" #include "blackbox.hh"
#include "Clientmenu.hh"
#include "Font.hh" #include "Font.hh"
#include "GCCache.hh" #include "GCCache.hh"
#include "Iconmenu.hh"
#include "Image.hh" #include "Image.hh"
#include "Rootmenu.hh"
#include "Screen.hh" #include "Screen.hh"
#include "Toolbar.hh" #include "Toolbar.hh"
#include "Window.hh" #include "Window.hh"
#include "Workspace.hh" #include "Workspace.hh"
#include "Clientmenu.hh"
#include "Workspacemenu.hh" #include "Workspacemenu.hh"
#include "Slit.hh" #include "Slit.hh"
@ -910,11 +908,10 @@ void Toolbar::keyPressEvent(const XKeyEvent *ke) {
editing = False; editing = False;
blackbox->setNoFocus(False); blackbox->setNoFocus(False);
if (blackbox->getFocusedWindow()) { if (blackbox->getFocusedWindow())
blackbox->getFocusedWindow()->setInputFocus(); blackbox->getFocusedWindow()->setInputFocus();
} else { else
blackbox->setFocusedWindow(0); blackbox->setFocusedWindow(0);
}
// the toolbar will be reconfigured when the change to the workspace name // the toolbar will be reconfigured when the change to the workspace name
// gets caught in the PropertyNotify event handler // gets caught in the PropertyNotify event handler

View file

@ -155,6 +155,8 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
current_state = NormalState; current_state = NormalState;
windowmenu = 0;
/* /*
get the initial size and location of client window (relative to the get the initial size and location of client window (relative to the
_root window_). This position is the reference point used with the _root window_). This position is the reference point used with the
@ -168,8 +170,6 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
timer = new BTimer(blackbox, this); timer = new BTimer(blackbox, this);
timer->setTimeout(blackbox->getAutoRaiseDelay()); timer->setTimeout(blackbox->getAutoRaiseDelay());
windowmenu = new Windowmenu(this);
// get size, aspect, minimum/maximum size and other hints set by the // get size, aspect, minimum/maximum size and other hints set by the
// client // client
@ -257,21 +257,6 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
screen->addStrut(&client.strut); screen->addStrut(&client.strut);
updateStrut(); updateStrut();
#ifdef SHAPE
if (blackbox->hasShapeExtensions() && flags.shaped)
configureShape();
#endif // SHAPE
// get the window's title before adding it to the workspace
getWMName();
getWMIconName();
if (blackbox_attrib.workspace >= screen->getWorkspaceCount())
screen->getCurrentWorkspace()->addWindow(this, place_window);
else
screen->getWorkspace(blackbox_attrib.workspace)->
addWindow(this, place_window);
/* /*
the server needs to be grabbed here to prevent client's from sending the server needs to be grabbed here to prevent client's from sending
events while we are in the process of configuring their window. events while we are in the process of configuring their window.
@ -284,6 +269,12 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
blackbox->saveWindowSearch(client.window, this); blackbox->saveWindowSearch(client.window, this);
if (blackbox_attrib.workspace >= screen->getWorkspaceCount())
screen->getCurrentWorkspace()->addWindow(this, place_window);
else
screen->getWorkspace(blackbox_attrib.workspace)->
addWindow(this, place_window);
if (! place_window) { if (! place_window) {
// don't need to call configure if we are letting the workspace // don't need to call configure if we are letting the workspace
// place the window // place the window
@ -296,6 +287,11 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
XUngrabServer(blackbox->getXDisplay()); XUngrabServer(blackbox->getXDisplay());
#ifdef SHAPE
if (blackbox->hasShapeExtensions() && flags.shaped)
configureShape();
#endif // SHAPE
// now that we know where to put the window and what it should look like // now that we know where to put the window and what it should look like
// we apply the decorations // we apply the decorations
decorate(); decorate();
@ -338,6 +334,9 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
if (flags.maximized && (functions & Func_Maximize)) if (flags.maximized && (functions & Func_Maximize))
remaximize(); remaximize();
// create this last so it only needs to be configured once
windowmenu = new Windowmenu(this);
} }
@ -369,18 +368,16 @@ BlackboxWindow::~BlackboxWindow(void) {
// remove ourselves from our transient_for // remove ourselves from our transient_for
if (isTransient()) { if (isTransient()) {
if (client.transient_for != (BlackboxWindow *) ~0ul) { if (client.transient_for != (BlackboxWindow *) ~0ul)
client.transient_for->client.transientList.remove(this); client.transient_for->client.transientList.remove(this);
}
client.transient_for = (BlackboxWindow*) 0; client.transient_for = (BlackboxWindow*) 0;
} }
if (client.transientList.size() > 0) { if (client.transientList.size() > 0) {
// reset transient_for for all transients // reset transient_for for all transients
BlackboxWindowList::iterator it, end = client.transientList.end(); BlackboxWindowList::iterator it, end = client.transientList.end();
for (it = client.transientList.begin(); it != end; ++it) { for (it = client.transientList.begin(); it != end; ++it)
(*it)->client.transient_for = (BlackboxWindow*) 0; (*it)->client.transient_for = (BlackboxWindow*) 0;
}
} }
if (frame.title) if (frame.title)
@ -417,7 +414,8 @@ Window BlackboxWindow::createToplevelWindow(void) {
attrib_create.colormap = screen->getColormap(); attrib_create.colormap = screen->getColormap();
attrib_create.override_redirect = True; attrib_create.override_redirect = True;
attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask | attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask |
ButtonMotionMask | EnterWindowMask; ButtonMotionMask |
EnterWindowMask | LeaveWindowMask;
return XCreateWindow(blackbox->getXDisplay(), screen->getRootWindow(), return XCreateWindow(blackbox->getXDisplay(), screen->getRootWindow(),
0, 0, 1, 1, frame.border_w, screen->getDepth(), 0, 0, 1, 1, frame.border_w, screen->getDepth(),
@ -452,6 +450,8 @@ Window BlackboxWindow::createChildWindow(Window parent, Cursor cursor) {
void BlackboxWindow::associateClientWindow(void) { void BlackboxWindow::associateClientWindow(void) {
XSetWindowBorderWidth(blackbox->getXDisplay(), client.window, 0); XSetWindowBorderWidth(blackbox->getXDisplay(), client.window, 0);
getWMName();
getWMIconName();
XChangeSaveSet(blackbox->getXDisplay(), client.window, SetModeInsert); XChangeSaveSet(blackbox->getXDisplay(), client.window, SetModeInsert);
@ -1417,9 +1417,22 @@ void BlackboxWindow::getTransientInfo(void) {
return; return;
} }
// register ourselves with our new transient_for // Check for a circular transient state: this can lock up Blackbox
client.transient_for->client.transientList.push_back(this); // when it tries to find the non-transient window for a transient.
flags.stuck = client.transient_for->flags.stuck; BlackboxWindow *w = this;
while(w->client.transient_for) {
if(w->client.transient_for == this) {
client.transient_for = (BlackboxWindow*) 0;
break;
}
w = w->client.transient_for;
}
if (client.transient_for) {
// register ourselves with our new transient_for
client.transient_for->client.transientList.push_back(this);
flags.stuck = client.transient_for->flags.stuck;
}
} }
@ -1559,9 +1572,8 @@ bool BlackboxWindow::setInputFocus(void) {
if (client.transientList.size() > 0) { if (client.transientList.size() > 0) {
// transfer focus to any modal transients // transfer focus to any modal transients
BlackboxWindowList::iterator it, end = client.transientList.end(); BlackboxWindowList::iterator it, end = client.transientList.end();
for (it = client.transientList.begin(); it != end; ++it) { for (it = client.transientList.begin(); it != end; ++it)
if ((*it)->flags.modal) return (*it)->setInputFocus(); if ((*it)->flags.modal) return (*it)->setInputFocus();
}
} }
bool ret = True; bool ret = True;
@ -1692,9 +1704,8 @@ void BlackboxWindow::deiconify(bool reassoc, bool raise) {
// reassociate and deiconify all transients // reassociate and deiconify all transients
if (reassoc && client.transientList.size() > 0) { if (reassoc && client.transientList.size() > 0) {
BlackboxWindowList::iterator it, end = client.transientList.end(); BlackboxWindowList::iterator it, end = client.transientList.end();
for (it = client.transientList.begin(); it != end; ++it) { for (it = client.transientList.begin(); it != end; ++it)
(*it)->deiconify(True, False); (*it)->deiconify(True, False);
}
} }
if (raise) if (raise)
@ -2064,18 +2075,13 @@ void BlackboxWindow::redrawWindowFrame(void) const {
void BlackboxWindow::setFocusFlag(bool focus) { void BlackboxWindow::setFocusFlag(bool focus) {
// only focus a window if it is visible // only focus a window if it is visible
if (focus && !flags.visible) if (focus && ! flags.visible)
return; return;
flags.focused = focus; flags.focused = focus;
redrawWindowFrame(); redrawWindowFrame();
if (screen->isSloppyFocus() && screen->doAutoRaise()) {
if (isFocused()) timer->start();
else timer->stop();
}
if (flags.focused) if (flags.focused)
blackbox->setFocusedWindow(this); blackbox->setFocusedWindow(this);
@ -3487,7 +3493,7 @@ void BlackboxWindow::beginResize(int x_root, int y_root, Corner dir) {
flags.resizing = True; flags.resizing = True;
blackbox->setChangingWindow(this); blackbox->setChangingWindow(this);
int gw, gh; unsigned int gw, gh;
frame.changing = frame.rect; frame.changing = frame.rect;
constrain(anchor, &gw, &gh); constrain(anchor, &gw, &gh);
@ -3511,7 +3517,7 @@ void BlackboxWindow::doResize(int x_root, int y_root) {
screen->getOpGC(), frame.changing.x(), frame.changing.y(), screen->getOpGC(), frame.changing.x(), frame.changing.y(),
frame.changing.width() - 1, frame.changing.height() - 1); frame.changing.width() - 1, frame.changing.height() - 1);
int gw, gh; unsigned int gw, gh;
Corner anchor; Corner anchor;
switch (resize_dir) { switch (resize_dir) {
@ -3627,6 +3633,43 @@ void BlackboxWindow::motionNotifyEvent(const XMotionEvent *me) {
} }
void BlackboxWindow::enterNotifyEvent(const XCrossingEvent* ce) {
if (! (screen->isSloppyFocus() && isVisible() && isNormal()))
return;
XEvent e;
bool leave = False, inferior = False;
while (XCheckTypedWindowEvent(blackbox->getXDisplay(), ce->window,
LeaveNotify, &e)) {
if (e.type == LeaveNotify && e.xcrossing.mode == NotifyNormal) {
leave = True;
inferior = (e.xcrossing.detail == NotifyInferior);
}
}
if ((! leave || inferior) && ! isFocused()) {
bool success = setInputFocus();
if (success) // if focus succeeded install the colormap
installColormap(True); // XXX: shouldnt we honour no install?
}
if (screen->doAutoRaise())
timer->start();
}
void BlackboxWindow::leaveNotifyEvent(const XCrossingEvent*) {
if (! (screen->isSloppyFocus() && screen->doAutoRaise() && isNormal()))
return;
installColormap(False);
if (timer->isTiming())
timer->stop();
}
#ifdef SHAPE #ifdef SHAPE
void BlackboxWindow::shapeEvent(XShapeEvent *) { void BlackboxWindow::shapeEvent(XShapeEvent *) {
if (blackbox->hasShapeExtensions() && flags.shaped) { if (blackbox->hasShapeExtensions() && flags.shaped) {
@ -3878,11 +3921,14 @@ void BlackboxWindow::upsize(void) {
* The logical width and height are placed into pw and ph, if they * The logical width and height are placed into pw and ph, if they
* are non-zero. Logical size refers to the users perception of * are non-zero. Logical size refers to the users perception of
* the window size (for example an xterm resizes in cells, not in pixels). * the window size (for example an xterm resizes in cells, not in pixels).
* pw and ph are then used to display the geometry during window moves, resize,
* etc.
* *
* The physical geometry is placed into frame.changing_{x,y,width,height}. * The physical geometry is placed into frame.changing_{x,y,width,height}.
* Physical geometry refers to the geometry of the window in pixels. * Physical geometry refers to the geometry of the window in pixels.
*/ */
void BlackboxWindow::constrain(Corner anchor, int *pw, int *ph) { void BlackboxWindow::constrain(Corner anchor,
unsigned int *pw, unsigned int *ph) {
// frame.changing represents the requested frame size, we need to // frame.changing represents the requested frame size, we need to
// strip the frame margin off and constrain the client size // strip the frame margin off and constrain the client size
frame.changing.setCoords(frame.changing.left() + frame.margin.left, frame.changing.setCoords(frame.changing.left() + frame.margin.left,
@ -3890,39 +3936,42 @@ void BlackboxWindow::constrain(Corner anchor, int *pw, int *ph) {
frame.changing.right() - frame.margin.right, frame.changing.right() - frame.margin.right,
frame.changing.bottom() - frame.margin.bottom); frame.changing.bottom() - frame.margin.bottom);
int dw = frame.changing.width(), dh = frame.changing.height(), unsigned int dw = frame.changing.width(), dh = frame.changing.height(),
base_width = (client.base_width) ? client.base_width : client.min_width, base_width = (client.base_width) ? client.base_width : client.min_width,
base_height = (client.base_height) ? client.base_height : base_height = (client.base_height) ? client.base_height :
client.min_height; client.min_height;
// constrain // constrain
if (dw < static_cast<signed>(client.min_width)) dw = client.min_width; if (dw < client.min_width) dw = client.min_width;
if (dh < static_cast<signed>(client.min_height)) dh = client.min_height; if (dh < client.min_height) dh = client.min_height;
if (dw > static_cast<signed>(client.max_width)) dw = client.max_width; if (dw > client.max_width) dw = client.max_width;
if (dh > static_cast<signed>(client.max_height)) dh = client.max_height; if (dh > client.max_height) dh = client.max_height;
dw -= base_width; assert(dw >= base_width && dh >= base_height);
dw /= client.width_inc;
dh -= base_height;
dh /= client.height_inc;
if (pw) { if (client.width_inc > 1) {
if (client.width_inc == 1) dw -= base_width;
*pw = dw + base_width; dw /= client.width_inc;
else
*pw = dw;
} }
if (ph) { if (client.height_inc > 1) {
if (client.height_inc == 1) dh -= base_height;
*ph = dh + base_height; dh /= client.height_inc;
else
*ph = dh;
} }
dw *= client.width_inc; if (pw)
dw += base_width; *pw = dw;
dh *= client.height_inc;
dh += base_height; if (ph)
*ph = dh;
if (client.width_inc > 1) {
dw *= client.width_inc;
dw += base_width;
}
if (client.height_inc > 1) {
dh *= client.height_inc;
dh += base_height;
}
frame.changing.setSize(dw, dh); frame.changing.setSize(dw, dh);
@ -4011,13 +4060,10 @@ BWindowGroup::find(BScreen *screen, bool allow_transients) const {
BlackboxWindow *ret = blackbox->getFocusedWindow(); BlackboxWindow *ret = blackbox->getFocusedWindow();
// does the focus window match (or any transient_fors)? // does the focus window match (or any transient_fors)?
while (ret) { for (; ret; ret = ret->getTransientFor()) {
if (ret->getScreen() == screen && ret->getGroupWindow() == group) { if (ret->getScreen() == screen && ret->getGroupWindow() == group &&
if (ret->isTransient() && allow_transients) break; (! ret->isTransient() || allow_transients))
else if (! ret->isTransient()) break; break;
}
ret = ret->getTransientFor();
} }
if (ret) return ret; if (ret) return ret;
@ -4026,10 +4072,9 @@ BWindowGroup::find(BScreen *screen, bool allow_transients) const {
BlackboxWindowList::const_iterator it, end = windowList.end(); BlackboxWindowList::const_iterator it, end = windowList.end();
for (it = windowList.begin(); it != end; ++it) { for (it = windowList.begin(); it != end; ++it) {
ret = *it; ret = *it;
if (ret->getScreen() == screen && ret->getGroupWindow() == group) { if (ret->getScreen() == screen && ret->getGroupWindow() == group &&
if (ret->isTransient() && allow_transients) break; (! ret->isTransient() || allow_transients))
else if (! ret->isTransient()) break; break;
}
} }
return ret; return ret;

View file

@ -301,7 +301,7 @@ private:
void doResize(int x_root, int y_root); void doResize(int x_root, int y_root);
void endResize(void); void endResize(void);
void constrain(Corner anchor, int *pw = 0, int *ph = 0); void constrain(Corner anchor, unsigned int *pw = 0, unsigned int *ph = 0);
public: public:
BlackboxWindow(Blackbox *b, Window w, BScreen *s); BlackboxWindow(Blackbox *b, Window w, BScreen *s);
@ -398,13 +398,15 @@ public:
void buttonPressEvent(const XButtonEvent *be); void buttonPressEvent(const XButtonEvent *be);
void buttonReleaseEvent(const XButtonEvent *re); void buttonReleaseEvent(const XButtonEvent *re);
void motionNotifyEvent(const XMotionEvent *me); void motionNotifyEvent(const XMotionEvent *me);
void destroyNotifyEvent(const XDestroyWindowEvent */*unused*/); void destroyNotifyEvent(const XDestroyWindowEvent* /*unused*/);
void mapRequestEvent(const XMapRequestEvent *mre); void mapRequestEvent(const XMapRequestEvent *mre);
void unmapNotifyEvent(const XUnmapEvent */*unused*/); void unmapNotifyEvent(const XUnmapEvent* /*unused*/);
void reparentNotifyEvent(const XReparentEvent */*unused*/); void reparentNotifyEvent(const XReparentEvent* /*unused*/);
void propertyNotifyEvent(const XPropertyEvent *pe); void propertyNotifyEvent(const XPropertyEvent *pe);
void exposeEvent(const XExposeEvent *ee); void exposeEvent(const XExposeEvent *ee);
void configureRequestEvent(const XConfigureRequestEvent *cr); void configureRequestEvent(const XConfigureRequestEvent *cr);
void enterNotifyEvent(const XCrossingEvent *ce);
void leaveNotifyEvent(const XCrossingEvent* /*unused*/);
#ifdef SHAPE #ifdef SHAPE
void configureShape(void); void configureShape(void);

View file

@ -222,36 +222,6 @@ void Workspace::setFocused(const BlackboxWindow *w, bool focused) {
} }
void Workspace::showAll(void) {
BlackboxWindowList::iterator it = stackingList.begin();
const BlackboxWindowList::iterator end = stackingList.end();
for (; it != end; ++it) {
BlackboxWindow *bw = *it;
// not normal windows cant focus from mouse enters anyways, so we dont
// need to unmap/remap them on workspace changes
if (! bw->isStuck() || bw->isNormal())
bw->show();
}
}
void Workspace::hideAll(void) {
// withdraw in reverse order to minimize the number of Expose events
BlackboxWindowList lst(stackingList.rbegin(), stackingList.rend());
BlackboxWindowList::iterator it = lst.begin();
const BlackboxWindowList::iterator end = lst.end();
for (; it != end; ++it) {
BlackboxWindow *bw = *it;
// not normal windows cant focus from mouse enters anyways, so we dont
// need to unmap/remap them on workspace changes
if (! bw->isStuck() || bw->isNormal())
bw->withdraw();
}
}
void Workspace::removeAll(void) { void Workspace::removeAll(void) {
while (! windowList.empty()) while (! windowList.empty())
windowList.front()->iconify(); windowList.front()->iconify();
@ -262,14 +232,16 @@ void Workspace::removeAll(void) {
* returns the number of transients for win, plus the number of transients * returns the number of transients for win, plus the number of transients
* associated with each transient of win * associated with each transient of win
*/ */
static int countTransients(const BlackboxWindow * const win) { static unsigned int countTransients(const BlackboxWindow * const win) {
int ret = win->getTransients().size(); BlackboxWindowList transients = win->getTransients();
if (ret > 0) { if (transients.empty()) return 0;
BlackboxWindowList::const_iterator it, end = win->getTransients().end();
for (it = win->getTransients().begin(); it != end; ++it) { unsigned int ret = transients.size();
ret += countTransients(*it); BlackboxWindowList::const_iterator it = transients.begin(),
} end = transients.end();
} for (; it != end; ++it)
ret += countTransients(*it);
return ret; return ret;
} }
@ -282,48 +254,48 @@ static int countTransients(const BlackboxWindow * const win) {
*/ */
void Workspace::raiseTransients(const BlackboxWindow * const win, void Workspace::raiseTransients(const BlackboxWindow * const win,
StackVector::iterator &stack) { StackVector::iterator &stack) {
if (win->getTransients().size() == 0) return; // nothing to do if (win->getTransients().empty()) return; // nothing to do
// put win's transients in the stack // put win's transients in the stack
BlackboxWindowList::const_iterator it, end = win->getTransients().end(); BlackboxWindowList::const_iterator it, end = win->getTransients().end();
for (it = win->getTransients().begin(); it != end; ++it) { for (it = win->getTransients().begin(); it != end; ++it) {
*stack++ = (*it)->getFrameWindow(); BlackboxWindow *w = *it;
screen->updateNetizenWindowRaise((*it)->getClientWindow()); *stack++ = w->getFrameWindow();
screen->updateNetizenWindowRaise(w->getClientWindow());
if (! (*it)->isIconic()) { if (! w->isIconic()) {
Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber()); Workspace *wkspc = screen->getWorkspace(w->getWorkspaceNumber());
wkspc->stackingList.remove((*it)); wkspc->stackingList.remove(w);
wkspc->stackingList.push_front((*it)); wkspc->stackingList.push_front(w);
} }
} }
// put transients of win's transients in the stack // put transients of win's transients in the stack
for (it = win->getTransients().begin(); it != end; ++it) { for (it = win->getTransients().begin(); it != end; ++it)
raiseTransients(*it, stack); raiseTransients(*it, stack);
}
} }
void Workspace::lowerTransients(const BlackboxWindow * const win, void Workspace::lowerTransients(const BlackboxWindow * const win,
StackVector::iterator &stack) { StackVector::iterator &stack) {
if (win->getTransients().size() == 0) return; // nothing to do if (win->getTransients().empty()) return; // nothing to do
// put transients of win's transients in the stack // put transients of win's transients in the stack
BlackboxWindowList::const_reverse_iterator it, BlackboxWindowList::const_reverse_iterator it,
end = win->getTransients().rend(); end = win->getTransients().rend();
for (it = win->getTransients().rbegin(); it != end; ++it) { for (it = win->getTransients().rbegin(); it != end; ++it)
lowerTransients(*it, stack); lowerTransients(*it, stack);
}
// put win's transients in the stack // put win's transients in the stack
for (it = win->getTransients().rbegin(); it != end; ++it) { for (it = win->getTransients().rbegin(); it != end; ++it) {
*stack++ = (*it)->getFrameWindow(); BlackboxWindow *w = *it;
screen->updateNetizenWindowLower((*it)->getClientWindow()); *stack++ = w->getFrameWindow();
screen->updateNetizenWindowLower(w->getClientWindow());
if (! (*it)->isIconic()) { if (! w->isIconic()) {
Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber()); Workspace *wkspc = screen->getWorkspace(w->getWorkspaceNumber());
wkspc->stackingList.remove((*it)); wkspc->stackingList.remove(w);
wkspc->stackingList.push_back((*it)); wkspc->stackingList.push_back(w);
} }
} }
} }
@ -335,10 +307,8 @@ void Workspace::raiseWindow(BlackboxWindow *w) {
if (win->isDesktop()) return; if (win->isDesktop()) return;
// walk up the transient_for's to the window that is not a transient // walk up the transient_for's to the window that is not a transient
while (win->isTransient() && ! win->isDesktop()) { while (win->isTransient() && win->getTransientFor())
if (! win->getTransientFor()) break;
win = win->getTransientFor(); win = win->getTransientFor();
}
// get the total window count (win and all transients) // get the total window count (win and all transients)
unsigned int i = 1 + countTransients(win); unsigned int i = 1 + countTransients(win);
@ -365,10 +335,8 @@ void Workspace::lowerWindow(BlackboxWindow *w) {
BlackboxWindow *win = w; BlackboxWindow *win = w;
// walk up the transient_for's to the window that is not a transient // walk up the transient_for's to the window that is not a transient
while (win->isTransient() && ! win->isDesktop()) { while (win->isTransient() && win->getTransientFor())
if (! win->getTransientFor()) break;
win = win->getTransientFor(); win = win->getTransientFor();
}
// get the total window count (win and all transients) // get the total window count (win and all transients)
unsigned int i = 1 + countTransients(win); unsigned int i = 1 + countTransients(win);
@ -401,9 +369,11 @@ void Workspace::reconfigure(void) {
BlackboxWindow *Workspace::getWindow(unsigned int index) { BlackboxWindow *Workspace::getWindow(unsigned int index) {
if (index < windowList.size()) { if (index < windowList.size()) {
BlackboxWindowList::iterator it = windowList.begin(); BlackboxWindowList::iterator it = windowList.begin();
for(; index > 0; --index, ++it); /* increment to index */ while (index-- > 0) // increment to index
++it;
return *it; return *it;
} }
return 0; return 0;
} }
@ -435,6 +405,7 @@ BlackboxWindow* Workspace::getPrevWindowInList(BlackboxWindow *w) {
BlackboxWindow* Workspace::getTopWindowOnStack(void) const { BlackboxWindow* Workspace::getTopWindowOnStack(void) const {
assert(! stackingList.empty());
return stackingList.front(); return stackingList.front();
} }
@ -461,6 +432,50 @@ void Workspace::appendStackOrder(BlackboxWindowList &stack_order) const {
} }
void Workspace::hide(void) {
BlackboxWindow *focused = screen->getBlackbox()->getFocusedWindow();
if (focused && focused->getScreen() == screen) {
assert(focused->isStuck() || focused->getWorkspaceNumber() == id);
lastfocus = focused;
} else {
// if no window had focus, no need to store a last focus
lastfocus = (BlackboxWindow *) 0;
}
// when we switch workspaces, unfocus whatever was focused
screen->getBlackbox()->setFocusedWindow((BlackboxWindow *) 0);
// withdraw windows in reverse order to minimize the number of Expose events
BlackboxWindowList::reverse_iterator it = stackingList.rbegin();
const BlackboxWindowList::reverse_iterator end = stackingList.rend();
for (; it != end; ++it) {
BlackboxWindow *bw = *it;
// not normal windows cant focus from mouse enters anyways, so we dont
// need to unmap/remap them on workspace changes
if (! bw->isStuck() || bw->isNormal())
bw->withdraw();
}
}
void Workspace::show(void) {
std::for_each(stackingList.begin(), stackingList.end(),
std::mem_fun(&BlackboxWindow::show));
XSync(screen->getBlackbox()->getXDisplay(), False);
if (screen->doFocusLast()) {
if (! screen->isSloppyFocus() && ! lastfocus && ! stackingList.empty())
lastfocus = stackingList.front();
if (lastfocus)
lastfocus->setInputFocus();
}
}
bool Workspace::isCurrent(void) const { bool Workspace::isCurrent(void) const {
return (id == screen->getCurrentWorkspaceID()); return (id == screen->getCurrentWorkspaceID());
} }

View file

@ -104,8 +104,8 @@ public:
unsigned int getCount(void) const; unsigned int getCount(void) const;
void appendStackOrder(BlackboxWindowList &stack_order) const; void appendStackOrder(BlackboxWindowList &stack_order) const;
void showAll(void); void show(void);
void hideAll(void); void hide(void);
void removeAll(void); void removeAll(void);
void raiseWindow(BlackboxWindow *w); void raiseWindow(BlackboxWindow *w);
void lowerWindow(BlackboxWindow *w); void lowerWindow(BlackboxWindow *w);

View file

@ -112,26 +112,6 @@ using std::string;
#include "Workspacemenu.hh" #include "Workspacemenu.hh"
#include "XAtom.hh" #include "XAtom.hh"
// X event scanner for enter/leave notifies - adapted from twm
struct scanargs {
Window w;
bool leave, inferior, enter;
};
static Bool queueScanner(Display *, XEvent *e, char *args) {
scanargs *scan = (scanargs *) args;
if ((e->type == LeaveNotify) &&
(e->xcrossing.window == scan->w) &&
(e->xcrossing.mode == NotifyNormal)) {
scan->leave = True;
scan->inferior = (e->xcrossing.detail == NotifyInferior);
} else if ((e->type == EnterNotify) && (e->xcrossing.mode == NotifyUngrab)) {
scan->enter = True;
}
return False;
}
Blackbox *blackbox; Blackbox *blackbox;
@ -474,24 +454,12 @@ void Blackbox::process_event(XEvent *e) {
if (e->xcrossing.mode == NotifyGrab) break; if (e->xcrossing.mode == NotifyGrab) break;
XEvent dummy;
scanargs sa;
sa.w = e->xcrossing.window;
sa.enter = sa.leave = False;
XCheckIfEvent(getXDisplay(), &dummy, queueScanner, (char *) &sa);
if ((e->xcrossing.window == e->xcrossing.root) && if ((e->xcrossing.window == e->xcrossing.root) &&
(screen = searchScreen(e->xcrossing.window))) { (screen = searchScreen(e->xcrossing.window))) {
screen->getImageControl()->installRootColormap(); screen->getImageControl()->installRootColormap();
} else if ((win = searchWindow(e->xcrossing.window))) { } else if ((win = searchWindow(e->xcrossing.window))) {
if (win->getScreen()->isSloppyFocus() && if (! no_focus)
(! win->isFocused()) && (! no_focus) && win->enterNotifyEvent(&e->xcrossing);
win->isNormal()) { // don't focus non-normal windows with mouseover
if ((! sa.leave || sa.inferior) && win->isVisible()) {
if (win->setInputFocus())
win->installColormap(True); // XXX: shouldnt we honour no install?
}
}
} else if ((menu = searchMenu(e->xcrossing.window))) { } else if ((menu = searchMenu(e->xcrossing.window))) {
menu->enterNotifyEvent(&e->xcrossing); menu->enterNotifyEvent(&e->xcrossing);
} else if ((tbar = searchToolbar(e->xcrossing.window))) { } else if ((tbar = searchToolbar(e->xcrossing.window))) {
@ -513,7 +481,7 @@ void Blackbox::process_event(XEvent *e) {
if ((menu = searchMenu(e->xcrossing.window))) if ((menu = searchMenu(e->xcrossing.window)))
menu->leaveNotifyEvent(&e->xcrossing); menu->leaveNotifyEvent(&e->xcrossing);
else if ((win = searchWindow(e->xcrossing.window))) else if ((win = searchWindow(e->xcrossing.window)))
win->installColormap(False); win->leaveNotifyEvent(&e->xcrossing);
else if ((tbar = searchToolbar(e->xcrossing.window))) else if ((tbar = searchToolbar(e->xcrossing.window)))
tbar->leaveNotifyEvent(&e->xcrossing); tbar->leaveNotifyEvent(&e->xcrossing);
else if ((slit = searchSlit(e->xcrossing.window))) else if ((slit = searchSlit(e->xcrossing.window)))