sync with blackbox
This commit is contained in:
parent
aa06c07dec
commit
72c56d793b
7 changed files with 224 additions and 211 deletions
|
@ -1129,7 +1129,8 @@ void BScreen::removeIcon(BlackboxWindow *w) {
|
|||
BlackboxWindow *BScreen::getIcon(unsigned int index) {
|
||||
if (index < iconList.size()) {
|
||||
BlackboxWindowList::iterator it = iconList.begin();
|
||||
for (; index > 0; --index, ++it) ; /* increment to index */
|
||||
while (index-- > 0) // increment to index
|
||||
++it;
|
||||
return *it;
|
||||
}
|
||||
|
||||
|
@ -1185,38 +1186,20 @@ unsigned int BScreen::removeLastWorkspace(void) {
|
|||
void BScreen::changeWorkspaceID(unsigned int id) {
|
||||
if (! current_workspace || id == current_workspace->getID()) return;
|
||||
|
||||
BlackboxWindow *focused = blackbox->getFocusedWindow();
|
||||
if (focused && focused->getScreen() == this) {
|
||||
assert(focused->isStuck() ||
|
||||
focused->getWorkspaceNumber() == current_workspace->getID());
|
||||
current_workspace->hide();
|
||||
|
||||
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);
|
||||
|
||||
current_workspace = getWorkspace(id);
|
||||
|
||||
current_workspace->show();
|
||||
|
||||
xatom->setValue(getRootWindow(), XAtom::net_current_desktop,
|
||||
XAtom::cardinal, id);
|
||||
|
||||
workspacemenu->setItemSelected(current_workspace->getID() + 2, True);
|
||||
toolbar->redrawWorkspaceLabel(True);
|
||||
|
||||
current_workspace->showAll();
|
||||
|
||||
if (resource.focus_last && current_workspace->getLastFocusedWindow()) {
|
||||
XSync(blackbox->getXDisplay(), False);
|
||||
current_workspace->getLastFocusedWindow()->setInputFocus();
|
||||
}
|
||||
|
||||
updateNetizenCurrentWorkspace();
|
||||
}
|
||||
|
||||
|
@ -1790,12 +1773,13 @@ void BScreen::InitMenu(void) {
|
|||
|
||||
|
||||
static
|
||||
void string_within(char begin, char end, const char *input, size_t length,
|
||||
size_t string_within(char begin, char end,
|
||||
const char *input, size_t start_at, size_t length,
|
||||
char *output) {
|
||||
bool parse = False;
|
||||
size_t index = 0;
|
||||
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
size_t i = start_at;
|
||||
for (; i < length; ++i) {
|
||||
if (input[i] == begin) {
|
||||
parse = True;
|
||||
} 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';
|
||||
else
|
||||
output[0] = '\0';
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1832,7 +1818,7 @@ bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) {
|
|||
unsigned int key = 0;
|
||||
|
||||
// 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
|
||||
continue;
|
||||
|
@ -1845,10 +1831,10 @@ bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) {
|
|||
}
|
||||
|
||||
// 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
|
||||
string_within('{', '}', line, line_length, command);
|
||||
pos = string_within('{', '}', line, pos, line_length, command);
|
||||
|
||||
switch (key) {
|
||||
case 311: // end
|
||||
|
|
|
@ -53,16 +53,14 @@ using std::string;
|
|||
|
||||
#include "i18n.hh"
|
||||
#include "blackbox.hh"
|
||||
#include "Clientmenu.hh"
|
||||
#include "Font.hh"
|
||||
#include "GCCache.hh"
|
||||
#include "Iconmenu.hh"
|
||||
#include "Image.hh"
|
||||
#include "Rootmenu.hh"
|
||||
#include "Screen.hh"
|
||||
#include "Toolbar.hh"
|
||||
#include "Window.hh"
|
||||
#include "Workspace.hh"
|
||||
#include "Clientmenu.hh"
|
||||
#include "Workspacemenu.hh"
|
||||
#include "Slit.hh"
|
||||
|
||||
|
@ -910,11 +908,10 @@ void Toolbar::keyPressEvent(const XKeyEvent *ke) {
|
|||
editing = False;
|
||||
|
||||
blackbox->setNoFocus(False);
|
||||
if (blackbox->getFocusedWindow()) {
|
||||
if (blackbox->getFocusedWindow())
|
||||
blackbox->getFocusedWindow()->setInputFocus();
|
||||
} else {
|
||||
else
|
||||
blackbox->setFocusedWindow(0);
|
||||
}
|
||||
|
||||
// the toolbar will be reconfigured when the change to the workspace name
|
||||
// gets caught in the PropertyNotify event handler
|
||||
|
|
167
src/Window.cc
167
src/Window.cc
|
@ -155,6 +155,8 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
|
||||
current_state = NormalState;
|
||||
|
||||
windowmenu = 0;
|
||||
|
||||
/*
|
||||
get the initial size and location of client window (relative to 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->setTimeout(blackbox->getAutoRaiseDelay());
|
||||
|
||||
windowmenu = new Windowmenu(this);
|
||||
|
||||
// get size, aspect, minimum/maximum size and other hints set by the
|
||||
// client
|
||||
|
||||
|
@ -257,21 +257,6 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
screen->addStrut(&client.strut);
|
||||
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
|
||||
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);
|
||||
|
||||
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) {
|
||||
// don't need to call configure if we are letting the workspace
|
||||
// place the window
|
||||
|
@ -296,6 +287,11 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
|
||||
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
|
||||
// we apply the decorations
|
||||
decorate();
|
||||
|
@ -338,6 +334,9 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
|
||||
if (flags.maximized && (functions & Func_Maximize))
|
||||
remaximize();
|
||||
|
||||
// create this last so it only needs to be configured once
|
||||
windowmenu = new Windowmenu(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -369,19 +368,17 @@ BlackboxWindow::~BlackboxWindow(void) {
|
|||
|
||||
// remove ourselves from our transient_for
|
||||
if (isTransient()) {
|
||||
if (client.transient_for != (BlackboxWindow *) ~0ul) {
|
||||
if (client.transient_for != (BlackboxWindow *) ~0ul)
|
||||
client.transient_for->client.transientList.remove(this);
|
||||
}
|
||||
client.transient_for = (BlackboxWindow*) 0;
|
||||
}
|
||||
|
||||
if (client.transientList.size() > 0) {
|
||||
// reset transient_for for all transients
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (frame.title)
|
||||
destroyTitlebar();
|
||||
|
@ -417,7 +414,8 @@ Window BlackboxWindow::createToplevelWindow(void) {
|
|||
attrib_create.colormap = screen->getColormap();
|
||||
attrib_create.override_redirect = True;
|
||||
attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask |
|
||||
ButtonMotionMask | EnterWindowMask;
|
||||
ButtonMotionMask |
|
||||
EnterWindowMask | LeaveWindowMask;
|
||||
|
||||
return XCreateWindow(blackbox->getXDisplay(), screen->getRootWindow(),
|
||||
0, 0, 1, 1, frame.border_w, screen->getDepth(),
|
||||
|
@ -452,6 +450,8 @@ Window BlackboxWindow::createChildWindow(Window parent, Cursor cursor) {
|
|||
|
||||
void BlackboxWindow::associateClientWindow(void) {
|
||||
XSetWindowBorderWidth(blackbox->getXDisplay(), client.window, 0);
|
||||
getWMName();
|
||||
getWMIconName();
|
||||
|
||||
XChangeSaveSet(blackbox->getXDisplay(), client.window, SetModeInsert);
|
||||
|
||||
|
@ -1417,10 +1417,23 @@ void BlackboxWindow::getTransientInfo(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Check for a circular transient state: this can lock up Blackbox
|
||||
// when it tries to find the non-transient window for a transient.
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BlackboxWindow *BlackboxWindow::getTransientFor(void) const {
|
||||
|
@ -1559,10 +1572,9 @@ bool BlackboxWindow::setInputFocus(void) {
|
|||
if (client.transientList.size() > 0) {
|
||||
// transfer focus to any modal transients
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
bool ret = True;
|
||||
if (focus_mode == F_LocallyActive || focus_mode == F_Passive) {
|
||||
|
@ -1692,10 +1704,9 @@ void BlackboxWindow::deiconify(bool reassoc, bool raise) {
|
|||
// reassociate and deiconify all transients
|
||||
if (reassoc && client.transientList.size() > 0) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (raise)
|
||||
screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
|
||||
|
@ -2071,11 +2082,6 @@ void BlackboxWindow::setFocusFlag(bool focus) {
|
|||
|
||||
redrawWindowFrame();
|
||||
|
||||
if (screen->isSloppyFocus() && screen->doAutoRaise()) {
|
||||
if (isFocused()) timer->start();
|
||||
else timer->stop();
|
||||
}
|
||||
|
||||
if (flags.focused)
|
||||
blackbox->setFocusedWindow(this);
|
||||
|
||||
|
@ -3487,7 +3493,7 @@ void BlackboxWindow::beginResize(int x_root, int y_root, Corner dir) {
|
|||
flags.resizing = True;
|
||||
blackbox->setChangingWindow(this);
|
||||
|
||||
int gw, gh;
|
||||
unsigned int gw, gh;
|
||||
frame.changing = frame.rect;
|
||||
|
||||
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(),
|
||||
frame.changing.width() - 1, frame.changing.height() - 1);
|
||||
|
||||
int gw, gh;
|
||||
unsigned int gw, gh;
|
||||
Corner anchor;
|
||||
|
||||
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
|
||||
void BlackboxWindow::shapeEvent(XShapeEvent *) {
|
||||
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
|
||||
* are non-zero. Logical size refers to the users perception of
|
||||
* 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}.
|
||||
* 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
|
||||
// strip the frame margin off and constrain the client size
|
||||
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.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_height = (client.base_height) ? client.base_height :
|
||||
client.min_height;
|
||||
|
||||
// constrain
|
||||
if (dw < static_cast<signed>(client.min_width)) dw = client.min_width;
|
||||
if (dh < static_cast<signed>(client.min_height)) dh = client.min_height;
|
||||
if (dw > static_cast<signed>(client.max_width)) dw = client.max_width;
|
||||
if (dh > static_cast<signed>(client.max_height)) dh = client.max_height;
|
||||
if (dw < client.min_width) dw = client.min_width;
|
||||
if (dh < client.min_height) dh = client.min_height;
|
||||
if (dw > client.max_width) dw = client.max_width;
|
||||
if (dh > client.max_height) dh = client.max_height;
|
||||
|
||||
assert(dw >= base_width && dh >= base_height);
|
||||
|
||||
if (client.width_inc > 1) {
|
||||
dw -= base_width;
|
||||
dw /= client.width_inc;
|
||||
}
|
||||
if (client.height_inc > 1) {
|
||||
dh -= base_height;
|
||||
dh /= client.height_inc;
|
||||
}
|
||||
|
||||
if (pw) {
|
||||
if (client.width_inc == 1)
|
||||
*pw = dw + base_width;
|
||||
else
|
||||
if (pw)
|
||||
*pw = dw;
|
||||
}
|
||||
if (ph) {
|
||||
if (client.height_inc == 1)
|
||||
*ph = dh + base_height;
|
||||
else
|
||||
*ph = dh;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -4011,13 +4060,10 @@ BWindowGroup::find(BScreen *screen, bool allow_transients) const {
|
|||
BlackboxWindow *ret = blackbox->getFocusedWindow();
|
||||
|
||||
// does the focus window match (or any transient_fors)?
|
||||
while (ret) {
|
||||
if (ret->getScreen() == screen && ret->getGroupWindow() == group) {
|
||||
if (ret->isTransient() && allow_transients) break;
|
||||
else if (! ret->isTransient()) break;
|
||||
}
|
||||
|
||||
ret = ret->getTransientFor();
|
||||
for (; ret; ret = ret->getTransientFor()) {
|
||||
if (ret->getScreen() == screen && ret->getGroupWindow() == group &&
|
||||
(! ret->isTransient() || allow_transients))
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret) return ret;
|
||||
|
@ -4026,10 +4072,9 @@ BWindowGroup::find(BScreen *screen, bool allow_transients) const {
|
|||
BlackboxWindowList::const_iterator it, end = windowList.end();
|
||||
for (it = windowList.begin(); it != end; ++it) {
|
||||
ret = *it;
|
||||
if (ret->getScreen() == screen && ret->getGroupWindow() == group) {
|
||||
if (ret->isTransient() && allow_transients) break;
|
||||
else if (! ret->isTransient()) break;
|
||||
}
|
||||
if (ret->getScreen() == screen && ret->getGroupWindow() == group &&
|
||||
(! ret->isTransient() || allow_transients))
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -301,7 +301,7 @@ private:
|
|||
void doResize(int x_root, int y_root);
|
||||
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:
|
||||
BlackboxWindow(Blackbox *b, Window w, BScreen *s);
|
||||
|
@ -405,6 +405,8 @@ public:
|
|||
void propertyNotifyEvent(const XPropertyEvent *pe);
|
||||
void exposeEvent(const XExposeEvent *ee);
|
||||
void configureRequestEvent(const XConfigureRequestEvent *cr);
|
||||
void enterNotifyEvent(const XCrossingEvent *ce);
|
||||
void leaveNotifyEvent(const XCrossingEvent* /*unused*/);
|
||||
|
||||
#ifdef SHAPE
|
||||
void configureShape(void);
|
||||
|
|
139
src/Workspace.cc
139
src/Workspace.cc
|
@ -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) {
|
||||
while (! windowList.empty())
|
||||
windowList.front()->iconify();
|
||||
|
@ -262,14 +232,16 @@ void Workspace::removeAll(void) {
|
|||
* returns the number of transients for win, plus the number of transients
|
||||
* associated with each transient of win
|
||||
*/
|
||||
static int countTransients(const BlackboxWindow * const win) {
|
||||
int ret = win->getTransients().size();
|
||||
if (ret > 0) {
|
||||
BlackboxWindowList::const_iterator it, end = win->getTransients().end();
|
||||
for (it = win->getTransients().begin(); it != end; ++it) {
|
||||
static unsigned int countTransients(const BlackboxWindow * const win) {
|
||||
BlackboxWindowList transients = win->getTransients();
|
||||
if (transients.empty()) return 0;
|
||||
|
||||
unsigned int ret = transients.size();
|
||||
BlackboxWindowList::const_iterator it = transients.begin(),
|
||||
end = transients.end();
|
||||
for (; it != end; ++it)
|
||||
ret += countTransients(*it);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -282,48 +254,48 @@ static int countTransients(const BlackboxWindow * const win) {
|
|||
*/
|
||||
void Workspace::raiseTransients(const BlackboxWindow * const win,
|
||||
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
|
||||
BlackboxWindowList::const_iterator it, end = win->getTransients().end();
|
||||
for (it = win->getTransients().begin(); it != end; ++it) {
|
||||
*stack++ = (*it)->getFrameWindow();
|
||||
screen->updateNetizenWindowRaise((*it)->getClientWindow());
|
||||
BlackboxWindow *w = *it;
|
||||
*stack++ = w->getFrameWindow();
|
||||
screen->updateNetizenWindowRaise(w->getClientWindow());
|
||||
|
||||
if (! (*it)->isIconic()) {
|
||||
Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber());
|
||||
wkspc->stackingList.remove((*it));
|
||||
wkspc->stackingList.push_front((*it));
|
||||
if (! w->isIconic()) {
|
||||
Workspace *wkspc = screen->getWorkspace(w->getWorkspaceNumber());
|
||||
wkspc->stackingList.remove(w);
|
||||
wkspc->stackingList.push_front(w);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Workspace::lowerTransients(const BlackboxWindow * const win,
|
||||
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
|
||||
BlackboxWindowList::const_reverse_iterator it,
|
||||
end = win->getTransients().rend();
|
||||
for (it = win->getTransients().rbegin(); it != end; ++it) {
|
||||
for (it = win->getTransients().rbegin(); it != end; ++it)
|
||||
lowerTransients(*it, stack);
|
||||
}
|
||||
|
||||
// put win's transients in the stack
|
||||
for (it = win->getTransients().rbegin(); it != end; ++it) {
|
||||
*stack++ = (*it)->getFrameWindow();
|
||||
screen->updateNetizenWindowLower((*it)->getClientWindow());
|
||||
BlackboxWindow *w = *it;
|
||||
*stack++ = w->getFrameWindow();
|
||||
screen->updateNetizenWindowLower(w->getClientWindow());
|
||||
|
||||
if (! (*it)->isIconic()) {
|
||||
Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber());
|
||||
wkspc->stackingList.remove((*it));
|
||||
wkspc->stackingList.push_back((*it));
|
||||
if (! w->isIconic()) {
|
||||
Workspace *wkspc = screen->getWorkspace(w->getWorkspaceNumber());
|
||||
wkspc->stackingList.remove(w);
|
||||
wkspc->stackingList.push_back(w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -335,10 +307,8 @@ void Workspace::raiseWindow(BlackboxWindow *w) {
|
|||
if (win->isDesktop()) return;
|
||||
|
||||
// walk up the transient_for's to the window that is not a transient
|
||||
while (win->isTransient() && ! win->isDesktop()) {
|
||||
if (! win->getTransientFor()) break;
|
||||
while (win->isTransient() && win->getTransientFor())
|
||||
win = win->getTransientFor();
|
||||
}
|
||||
|
||||
// get the total window count (win and all transients)
|
||||
unsigned int i = 1 + countTransients(win);
|
||||
|
@ -365,10 +335,8 @@ void Workspace::lowerWindow(BlackboxWindow *w) {
|
|||
BlackboxWindow *win = w;
|
||||
|
||||
// walk up the transient_for's to the window that is not a transient
|
||||
while (win->isTransient() && ! win->isDesktop()) {
|
||||
if (! win->getTransientFor()) break;
|
||||
while (win->isTransient() && win->getTransientFor())
|
||||
win = win->getTransientFor();
|
||||
}
|
||||
|
||||
// get the total window count (win and all transients)
|
||||
unsigned int i = 1 + countTransients(win);
|
||||
|
@ -401,9 +369,11 @@ void Workspace::reconfigure(void) {
|
|||
BlackboxWindow *Workspace::getWindow(unsigned int index) {
|
||||
if (index < windowList.size()) {
|
||||
BlackboxWindowList::iterator it = windowList.begin();
|
||||
for(; index > 0; --index, ++it); /* increment to index */
|
||||
while (index-- > 0) // increment to index
|
||||
++it;
|
||||
return *it;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -435,6 +405,7 @@ BlackboxWindow* Workspace::getPrevWindowInList(BlackboxWindow *w) {
|
|||
|
||||
|
||||
BlackboxWindow* Workspace::getTopWindowOnStack(void) const {
|
||||
assert(! stackingList.empty());
|
||||
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 {
|
||||
return (id == screen->getCurrentWorkspaceID());
|
||||
}
|
||||
|
|
|
@ -104,8 +104,8 @@ public:
|
|||
unsigned int getCount(void) const;
|
||||
void appendStackOrder(BlackboxWindowList &stack_order) const;
|
||||
|
||||
void showAll(void);
|
||||
void hideAll(void);
|
||||
void show(void);
|
||||
void hide(void);
|
||||
void removeAll(void);
|
||||
void raiseWindow(BlackboxWindow *w);
|
||||
void lowerWindow(BlackboxWindow *w);
|
||||
|
|
|
@ -112,26 +112,6 @@ using std::string;
|
|||
#include "Workspacemenu.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;
|
||||
|
||||
|
||||
|
@ -474,24 +454,12 @@ void Blackbox::process_event(XEvent *e) {
|
|||
|
||||
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) &&
|
||||
(screen = searchScreen(e->xcrossing.window))) {
|
||||
screen->getImageControl()->installRootColormap();
|
||||
} else if ((win = searchWindow(e->xcrossing.window))) {
|
||||
if (win->getScreen()->isSloppyFocus() &&
|
||||
(! win->isFocused()) && (! no_focus) &&
|
||||
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?
|
||||
}
|
||||
}
|
||||
if (! no_focus)
|
||||
win->enterNotifyEvent(&e->xcrossing);
|
||||
} else if ((menu = searchMenu(e->xcrossing.window))) {
|
||||
menu->enterNotifyEvent(&e->xcrossing);
|
||||
} else if ((tbar = searchToolbar(e->xcrossing.window))) {
|
||||
|
@ -513,7 +481,7 @@ void Blackbox::process_event(XEvent *e) {
|
|||
if ((menu = searchMenu(e->xcrossing.window)))
|
||||
menu->leaveNotifyEvent(&e->xcrossing);
|
||||
else if ((win = searchWindow(e->xcrossing.window)))
|
||||
win->installColormap(False);
|
||||
win->leaveNotifyEvent(&e->xcrossing);
|
||||
else if ((tbar = searchToolbar(e->xcrossing.window)))
|
||||
tbar->leaveNotifyEvent(&e->xcrossing);
|
||||
else if ((slit = searchSlit(e->xcrossing.window)))
|
||||
|
|
Loading…
Reference in a new issue