summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/BaseDisplay.cc7
-rw-r--r--src/Configmenu.cc3
-rw-r--r--src/Screen.cc17
-rw-r--r--src/Screen.hh3
-rw-r--r--src/Slit.cc10
-rw-r--r--src/Slit.hh10
-rw-r--r--src/Toolbar.cc14
-rw-r--r--src/Toolbar.hh12
-rw-r--r--src/Window.cc250
-rw-r--r--src/Window.hh5
-rw-r--r--src/Workspace.cc15
-rw-r--r--src/Workspace.hh1
-rw-r--r--src/blackbox.cc17
13 files changed, 198 insertions, 166 deletions
diff --git a/src/BaseDisplay.cc b/src/BaseDisplay.cc
index 21f9ab53..aa2d974e 100644
--- a/src/BaseDisplay.cc
+++ b/src/BaseDisplay.cc
@@ -78,7 +78,7 @@ extern "C" {
#endif // HAVE_SYS_WAIT_H
}
-#include <sstream>
+#include <string>
using std::string;
#include "i18n.hh"
@@ -468,7 +468,6 @@ ScreenInfo::ScreenInfo(BaseDisplay *d, unsigned int num) {
if (pos != string::npos)
default_string.resize(pos);
- std::ostringstream formatter;
- formatter << "DISPLAY=" << default_string << '.' << screen_number;
- display_string = formatter.str();
+ display_string = string("DISPLAY=") + default_string + '.' +
+ itostring(static_cast<unsigned long>(screen_number));
}
diff --git a/src/Configmenu.cc b/src/Configmenu.cc
index 3a8a6e45..d78d3da9 100644
--- a/src/Configmenu.cc
+++ b/src/Configmenu.cc
@@ -200,7 +200,8 @@ void Configmenu::Focusmenu::itemSelected(int button, unsigned int index) {
case 4: // click raise with sloppy focus
getScreen()->saveClickRaise(! getScreen()->doClickRaise());
- getScreen()->updateFocusModel();
+ // make sure the appropriate mouse buttons are grabbed on the windows
+ getScreen()->toggleFocusModel(BScreen::SloppyFocus);
break;
}
setValues();
diff --git a/src/Screen.cc b/src/Screen.cc
index a05c2386..1879976f 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -132,6 +132,8 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) {
resource.mstyle.t_font = resource.mstyle.f_font = resource.tstyle.font =
resource.wstyle.font = (BFont *) 0;
+ geom_pixmap = None;
+
xatom->setSupported(this); // set-up netwm support
#ifdef HAVE_GETPID
xatom->setValue(getRootWindow(), XAtom::blackbox_pid, XAtom::cardinal,
@@ -2006,7 +2008,7 @@ Workspace* BScreen::getWorkspace(unsigned int index) {
}
-void BScreen::buttonPressEvent(XButtonEvent *xbutton) {
+void BScreen::buttonPressEvent(const XButtonEvent *xbutton) {
if (xbutton->button == 1) {
if (! isRootColormapInstalled())
image_control->installRootColormap();
@@ -2071,6 +2073,9 @@ void BScreen::buttonPressEvent(XButtonEvent *xbutton) {
void BScreen::toggleFocusModel(FocusModel model) {
+ std::for_each(windowList.begin(), windowList.end(),
+ std::mem_fun(&BlackboxWindow::ungrabButtons));
+
if (model == SloppyFocus) {
saveSloppyFocus(True);
} else {
@@ -2080,14 +2085,8 @@ void BScreen::toggleFocusModel(FocusModel model) {
saveSloppyFocus(False);
}
- updateFocusModel();
-}
-
-
-void BScreen::updateFocusModel()
-{
- std::for_each(workspacesList.begin(), workspacesList.end(),
- std::mem_fun(&Workspace::updateFocusModel));
+ std::for_each(windowList.begin(), windowList.end(),
+ std::mem_fun(&BlackboxWindow::grabButtons));
}
diff --git a/src/Screen.hh b/src/Screen.hh
index 60418cd7..3ce57db3 100644
--- a/src/Screen.hh
+++ b/src/Screen.hh
@@ -331,14 +331,13 @@ public:
void save_rc(void);
void reconfigure(void);
void toggleFocusModel(FocusModel model);
- void updateFocusModel(void);
void rereadMenu(void);
void shutdown(void);
void showPosition(int x, int y);
void showGeometry(unsigned int gx, unsigned int gy);
void hideGeometry(void);
- void buttonPressEvent(XButtonEvent *xbutton);
+ void buttonPressEvent(const XButtonEvent *xbutton);
void updateNetizenCurrentWorkspace(void);
void updateNetizenWorkspaceCount(void);
diff --git a/src/Slit.cc b/src/Slit.cc
index 171432af..336daeb3 100644
--- a/src/Slit.cc
+++ b/src/Slit.cc
@@ -625,7 +625,7 @@ void Slit::shutdown(void) {
}
-void Slit::buttonPressEvent(XButtonEvent *e) {
+void Slit::buttonPressEvent(const XButtonEvent *e) {
if (e->window != frame.window) return;
if (e->button == Button1 && (! on_top)) {
@@ -659,7 +659,7 @@ void Slit::buttonPressEvent(XButtonEvent *e) {
}
-void Slit::enterNotifyEvent(XCrossingEvent *) {
+void Slit::enterNotifyEvent(const XCrossingEvent *) {
if (! do_auto_hide)
return;
@@ -671,7 +671,7 @@ void Slit::enterNotifyEvent(XCrossingEvent *) {
}
-void Slit::leaveNotifyEvent(XCrossingEvent *) {
+void Slit::leaveNotifyEvent(const XCrossingEvent *) {
if (! do_auto_hide)
return;
@@ -683,7 +683,7 @@ void Slit::leaveNotifyEvent(XCrossingEvent *) {
}
-void Slit::configureRequestEvent(XConfigureRequestEvent *e) {
+void Slit::configureRequestEvent(const XConfigureRequestEvent *e) {
if (! blackbox->validateWindow(e->window))
return;
@@ -737,7 +737,7 @@ void Slit::toggleAutoHide(void) {
}
-void Slit::unmapNotifyEvent(XUnmapEvent *e) {
+void Slit::unmapNotifyEvent(const XUnmapEvent *e) {
removeClient(e->window);
}
diff --git a/src/Slit.hh b/src/Slit.hh
index 85b49d7d..798ccb24 100644
--- a/src/Slit.hh
+++ b/src/Slit.hh
@@ -188,11 +188,11 @@ public:
void shutdown(void);
void toggleAutoHide(void);
- void buttonPressEvent(XButtonEvent *e);
- void enterNotifyEvent(XCrossingEvent * /*unused*/);
- void leaveNotifyEvent(XCrossingEvent * /*unused*/);
- void configureRequestEvent(XConfigureRequestEvent *e);
- void unmapNotifyEvent(XUnmapEvent *e);
+ void buttonPressEvent(const XButtonEvent *e);
+ void enterNotifyEvent(const XCrossingEvent * /*unused*/);
+ void leaveNotifyEvent(const XCrossingEvent * /*unused*/);
+ void configureRequestEvent(const XConfigureRequestEvent *e);
+ void unmapNotifyEvent(const XUnmapEvent *e);
virtual void timeout(void);
diff --git a/src/Toolbar.cc b/src/Toolbar.cc
index f6ff130a..2890fa26 100644
--- a/src/Toolbar.cc
+++ b/src/Toolbar.cc
@@ -777,7 +777,7 @@ void Toolbar::edit(void) {
}
-void Toolbar::buttonPressEvent(XButtonEvent *be) {
+void Toolbar::buttonPressEvent(const XButtonEvent *be) {
if (be->button == 1) {
if (be->window == frame.psbutton)
redrawPrevWorkspaceButton(True, True);
@@ -826,7 +826,7 @@ void Toolbar::buttonPressEvent(XButtonEvent *be) {
-void Toolbar::buttonReleaseEvent(XButtonEvent *re) {
+void Toolbar::buttonReleaseEvent(const XButtonEvent *re) {
if (re->button == 1) {
if (re->window == frame.psbutton) {
redrawPrevWorkspaceButton(False, True);
@@ -873,7 +873,7 @@ void Toolbar::buttonReleaseEvent(XButtonEvent *re) {
}
-void Toolbar::enterNotifyEvent(XCrossingEvent *) {
+void Toolbar::enterNotifyEvent(const XCrossingEvent *) {
if (! do_auto_hide)
return;
@@ -884,7 +884,7 @@ void Toolbar::enterNotifyEvent(XCrossingEvent *) {
}
}
-void Toolbar::leaveNotifyEvent(XCrossingEvent *) {
+void Toolbar::leaveNotifyEvent(const XCrossingEvent *) {
if (! do_auto_hide)
return;
@@ -896,7 +896,7 @@ void Toolbar::leaveNotifyEvent(XCrossingEvent *) {
}
-void Toolbar::exposeEvent(XExposeEvent *ee) {
+void Toolbar::exposeEvent(const XExposeEvent *ee) {
if (ee->window == frame.clock) checkClock(True);
else if (ee->window == frame.workspace_label && (! editing))
redrawWorkspaceLabel();
@@ -908,7 +908,7 @@ void Toolbar::exposeEvent(XExposeEvent *ee) {
}
-void Toolbar::keyPressEvent(XKeyEvent *ke) {
+void Toolbar::keyPressEvent(const XKeyEvent *ke) {
if (ke->window == frame.workspace_label && editing) {
if (new_workspace_name.empty()) {
new_name_pos = 0;
@@ -916,7 +916,7 @@ void Toolbar::keyPressEvent(XKeyEvent *ke) {
KeySym ks;
char keychar[1];
- XLookupString(ke, keychar, 1, &ks, 0);
+ XLookupString(const_cast<XKeyEvent*>(ke), keychar, 1, &ks, 0);
// either we are told to end with a return or we hit 127 chars
if (ks == XK_Return || new_name_pos == 127) {
diff --git a/src/Toolbar.hh b/src/Toolbar.hh
index f9dd5481..ae8353ba 100644
--- a/src/Toolbar.hh
+++ b/src/Toolbar.hh
@@ -172,12 +172,12 @@ public:
inline int getY(void) const
{ return ((hidden) ? frame.y_hidden : frame.rect.y()); }
- void buttonPressEvent(XButtonEvent *be);
- void buttonReleaseEvent(XButtonEvent *re);
- void enterNotifyEvent(XCrossingEvent * /*unused*/);
- void leaveNotifyEvent(XCrossingEvent * /*unused*/);
- void exposeEvent(XExposeEvent *ee);
- void keyPressEvent(XKeyEvent *ke);
+ void buttonPressEvent(const XButtonEvent *be);
+ void buttonReleaseEvent(const XButtonEvent *re);
+ void enterNotifyEvent(const XCrossingEvent * /*unused*/);
+ void leaveNotifyEvent(const XCrossingEvent * /*unused*/);
+ void exposeEvent(const XExposeEvent *ee);
+ void keyPressEvent(const XKeyEvent *ke);
void edit(void);
void reconfigure(void);
diff --git a/src/Window.cc b/src/Window.cc
index 803cd9af..f1dfe6e8 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -134,13 +134,14 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
frame.fgrip_pixel = 0;
frame.utitle = frame.ftitle = frame.uhandle = frame.fhandle = None;
frame.ulabel = frame.flabel = frame.ubutton = frame.fbutton = None;
- frame.pbutton = frame.ugrip = frame.fgrip = decorations;
+ frame.pbutton = frame.ugrip = frame.fgrip = None;
decorations = Decor_Titlebar | Decor_Border | Decor_Handle |
Decor_Iconify | Decor_Maximize;
functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize;
client.wm_hint_flags = client.normal_hint_flags = 0;
+ client.window_group = None;
client.transient_for = 0;
/*
@@ -271,32 +272,7 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
}
#endif // SHAPE
- if ((! screen->isSloppyFocus()) || screen->doClickRaise()) {
- // grab button 1 for changing focus/raising
- blackbox->grabButton(Button1, 0, frame.plate, True, ButtonPressMask,
- GrabModeSync, GrabModeSync, None, None);
- }
-
- if (functions & Func_Move)
- blackbox->grabButton(Button1, Mod1Mask, frame.window, True,
- ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
- GrabModeAsync, frame.window,
- blackbox->getMoveCursor());
- blackbox->grabButton(Button2, Mod1Mask, frame.window, True,
- ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
- None, None);
- if (functions & Func_Resize)
- blackbox->grabButton(Button3, Mod1Mask, frame.window, True,
- ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
- GrabModeAsync, None,
- blackbox->getLowerRightAngleCursor());
-
- positionWindows();
- decorate();
-
- if (decorations & Decor_Titlebar)
- XMapSubwindows(blackbox->getXDisplay(), frame.title);
- XMapSubwindows(blackbox->getXDisplay(), frame.window);
+ grabButtons();
windowmenu = new Windowmenu(this);
@@ -329,16 +305,15 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
if (flags.shaded) {
flags.shaded = False;
+ unsigned long orig_state = current_state;
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 (orig_state != IconicState)
+ current_state = NormalState;
}
if (flags.stuck) {
@@ -359,6 +334,11 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
fact never set to Iconic since there is no way for us to tell if a sticky
window was iconified previously.
*/
+
+ positionWindows();
+ decorate();
+
+ XMapSubwindows(blackbox->getXDisplay(), frame.window);
redrawWindowFrame();
}
@@ -838,17 +818,11 @@ void BlackboxWindow::positionButtons(bool redecorate_label) {
void BlackboxWindow::reconfigure(void) {
upsize();
- client.rect.setPos(frame.rect.left() + frame.margin.left,
- frame.rect.top() + frame.margin.top);
-
positionWindows();
decorate();
redrawWindowFrame();
- configure(frame.rect.x(), frame.rect.y(),
- frame.rect.width(), frame.rect.height());
-
if (windowmenu) {
windowmenu->move(windowmenu->getX(), frame.rect.y() + frame.title_h);
windowmenu->reconfigure();
@@ -856,14 +830,31 @@ void BlackboxWindow::reconfigure(void) {
}
-void BlackboxWindow::updateFocusModel(void) {
- if ((! screen->isSloppyFocus()) || screen->doClickRaise()) {
+void BlackboxWindow::grabButtons(void) {
+ if ((! screen->isSloppyFocus()) || screen->doClickRaise())
// grab button 1 for changing focus/raising
blackbox->grabButton(Button1, 0, frame.plate, True, ButtonPressMask,
- GrabModeSync, GrabModeSync, None, None);
- } else {
+ GrabModeSync, GrabModeSync, frame.plate, None);
+
+ if (functions & Func_Move)
+ blackbox->grabButton(Button1, Mod1Mask, frame.window, True,
+ ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
+ GrabModeAsync, frame.window,
+ blackbox->getMoveCursor());
+ if (functions & Func_Resize)
+ blackbox->grabButton(Button3, Mod1Mask, frame.window, True,
+ ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
+ GrabModeAsync, frame.window,
+ blackbox->getLowerRightAngleCursor());
+}
+
+
+void BlackboxWindow::ungrabButtons(void) {
+ if ((! screen->isSloppyFocus()) || screen->doClickRaise())
blackbox->ungrabButton(Button1, 0, frame.plate);
- }
+
+ blackbox->ungrabButton(Button1, Mod1Mask, frame.window);
+ blackbox->ungrabButton(Button3, Mod1Mask, frame.window);
}
@@ -881,6 +872,11 @@ void BlackboxWindow::positionWindows(void) {
client.rect.width(), client.rect.height());
XMoveResizeWindow(blackbox->getXDisplay(), client.window,
0, 0, client.rect.width(), client.rect.height());
+ // ensure client.rect contains the real location
+ client.rect.setCoords(frame.rect.left() + frame.margin.left,
+ frame.rect.top() + frame.margin.top,
+ frame.rect.right() - frame.margin.right,
+ frame.rect.bottom() - frame.margin.bottom);
if (decorations & Decor_Titlebar) {
if (frame.title == None) createTitlebar();
@@ -1435,9 +1431,15 @@ BlackboxWindow *BlackboxWindow::getTransientFor(void) const {
}
+/*
+ * This function is responsible for updating both the client and the frame
+ * rectangles.
+ * According to the ICCCM a client message is not sent for a resize, only a
+ * move.
+ */
void BlackboxWindow::configure(int dx, int dy,
unsigned int dw, unsigned int dh) {
- bool send_event = False;
+ bool send_event = (frame.rect.x() != dx || frame.rect.y() != dy);
if (dw != frame.rect.width() || dh != frame.rect.height()) {
frame.rect.setRect(dx, dy, dw, dh);
@@ -1461,9 +1463,7 @@ void BlackboxWindow::configure(int dx, int dy,
positionWindows();
decorate();
redrawWindowFrame();
- } else if (frame.rect.x() != dx || frame.rect.y() != dy) {
- send_event = True;
-
+ } else {
frame.rect.setPos(dx, dy);
XMoveWindow(blackbox->getXDisplay(), frame.window,
@@ -1471,6 +1471,7 @@ void BlackboxWindow::configure(int dx, int dy,
}
if (send_event && ! flags.moving) {
+ // if moving, the update and event will occur when the move finishes
client.rect.setPos(frame.rect.left() + frame.margin.left,
frame.rect.top() + frame.margin.top);
@@ -1490,7 +1491,6 @@ void BlackboxWindow::configure(int dx, int dy,
XSendEvent(blackbox->getXDisplay(), client.window, False,
StructureNotifyMask, &event);
-
screen->updateNetizenConfigNotify(&event);
}
}
@@ -1532,8 +1532,10 @@ void BlackboxWindow::configureShape(void) {
bool BlackboxWindow::setInputFocus(void) {
if (flags.focused) return True;
- assert(! flags.iconic);
-
+ assert(! flags.iconic &&
+ (flags.stuck || // window must be on the current workspace or sticky
+ blackbox_attrib.workspace == screen->getCurrentWorkspaceID()));
+#if 0
// if the window is not visible, mark the window as wanting focus rather
// than give it focus.
if (! flags.visible) {
@@ -1541,7 +1543,7 @@ bool BlackboxWindow::setInputFocus(void) {
wkspc->setLastFocusedWindow(this);
return True;
}
-
+#endif
if (! frame.rect.intersects(screen->getRect())) {
// client is outside the screen, move it to the center
configure((screen->getWidth() - frame.rect.width()) / 2,
@@ -1653,13 +1655,24 @@ void BlackboxWindow::show(void) {
XMapWindow(blackbox->getXDisplay(), client.window);
XMapSubwindows(blackbox->getXDisplay(), frame.window);
XMapWindow(blackbox->getXDisplay(), frame.window);
+
+#ifdef DEBUG
+ int real_x, real_y;
+ Window child;
+ XTranslateCoordinates(blackbox->getXDisplay(), client.window,
+ screen->getRootWindow(),
+ 0, 0, &real_x, &real_y, &child);
+ fprintf(stderr, "%s -- assumed: (%d, %d), real: (%d, %d)\n", getTitle(),
+ client.rect.left(), client.rect.top(), real_x, real_y);
+ assert(client.rect.left() == real_x && client.rect.top() == real_y);
+#endif
}
void BlackboxWindow::deiconify(bool reassoc, bool raise) {
if (flags.iconic || reassoc)
screen->reassociateWindow(this, BSENTINEL, False);
- else if (blackbox_attrib.workspace != screen->getCurrentWorkspace()->getID())
+ else if (blackbox_attrib.workspace != screen->getCurrentWorkspaceID())
return;
show();
@@ -2116,20 +2129,19 @@ void BlackboxWindow::restoreAttributes(void) {
if (net->flags & AttribShaded && net->attrib & AttribShaded) {
flags.shaded = False;
+ unsigned long orig_state = current_state;
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 (orig_state != IconicState)
+ current_state = WithdrawnState;
}
- if ((net->workspace != screen->getCurrentWorkspaceID()) &&
- (net->workspace < screen->getWorkspaceCount()))
+ if (net->workspace != screen->getCurrentWorkspaceID() &&
+ net->workspace < screen->getWorkspaceCount())
screen->reassociateWindow(this, net->workspace, True);
if ((blackbox_attrib.workspace != screen->getCurrentWorkspaceID()) &&
@@ -2521,8 +2533,16 @@ void BlackboxWindow::reparentNotifyEvent(const XReparentEvent *re) {
}
-void BlackboxWindow::propertyNotifyEvent(Atom atom) {
- switch(atom) {
+void BlackboxWindow::propertyNotifyEvent(const XPropertyEvent *pe) {
+ if (pe->state == PropertyDelete)
+ return;
+
+#ifdef DEBUG
+ fprintf(stderr, "BlackboxWindow::propertyNotifyEvent(): for 0x%lx\n",
+ client.window);
+#endif
+
+ switch(pe->atom) {
case XA_WM_CLASS:
case XA_WM_CLIENT_MACHINE:
case XA_WM_COMMAND:
@@ -2567,6 +2587,9 @@ void BlackboxWindow::propertyNotifyEvent(Atom atom) {
if ((client.normal_hint_flags & PMinSize) &&
(client.normal_hint_flags & PMaxSize)) {
+ // the window now can/can't resize itself, so the buttons need to be
+ // regrabbed.
+ ungrabButtons();
if (client.max_width <= client.min_width &&
client.max_height <= client.min_height) {
decorations &= ~(Decor_Maximize | Decor_Handle);
@@ -2575,6 +2598,7 @@ void BlackboxWindow::propertyNotifyEvent(Atom atom) {
decorations |= Decor_Maximize | Decor_Handle;
functions |= Func_Resize | Func_Maximize;
}
+ grabButtons();
setAllowedActions();
}
@@ -2589,7 +2613,7 @@ void BlackboxWindow::propertyNotifyEvent(Atom atom) {
}
default:
- if (atom == xatom->getAtom(XAtom::wm_protocols)) {
+ if (pe->atom == xatom->getAtom(XAtom::wm_protocols)) {
getWMProtocols();
if ((decorations & Decor_Close) && (! frame.close_button)) {
@@ -2600,7 +2624,7 @@ void BlackboxWindow::propertyNotifyEvent(Atom atom) {
}
if (windowmenu) windowmenu->reconfigure();
}
- } else if (atom == xatom->getAtom(XAtom::net_wm_strut)) {
+ } else if (pe->atom == xatom->getAtom(XAtom::net_wm_strut)) {
updateStrut();
}
@@ -2610,6 +2634,10 @@ void BlackboxWindow::propertyNotifyEvent(Atom atom) {
void BlackboxWindow::exposeEvent(const XExposeEvent *ee) {
+#ifdef DEBUG
+ fprintf(stderr, "BlackboxWindow::exposeEvent() for 0x%lx\n", client.window);
+#endif
+
if (frame.label == ee->window && (decorations & Decor_Titlebar))
redrawLabel();
else if (frame.close_button == ee->window)
@@ -2667,6 +2695,11 @@ void BlackboxWindow::configureRequestEvent(const XConfigureRequestEvent *cr) {
void BlackboxWindow::buttonPressEvent(const XButtonEvent *be) {
+#ifdef DEBUG
+ fprintf(stderr, "BlackboxWindow::buttonPressEvent() for 0x%lx\n",
+ client.window);
+#endif
+
if (frame.maximize_button == be->window) {
redrawMaximizeButton(True);
} else if (be->button == 1 || (be->button == 3 && be->state == Mod1Mask)) {
@@ -2705,51 +2738,42 @@ void BlackboxWindow::buttonPressEvent(const XButtonEvent *be) {
} else if (windowmenu && be->button == 3 &&
(frame.title == be->window || frame.label == be->window ||
frame.handle == be->window || frame.window == be->window)) {
- int mx = 0, my = 0;
-
- if (frame.title == be->window || frame.label == be->window) {
- mx = be->x_root - (windowmenu->getWidth() / 2);
- my = frame.rect.y() + frame.title_h + frame.border_w;
- } else if (frame.handle == be->window) {
- mx = be->x_root - (windowmenu->getWidth() / 2);
- my = frame.rect.bottom() - frame.handle_h - (frame.border_w * 3) -
- windowmenu->getHeight();
+ if (windowmenu->isVisible()) {
+ windowmenu->hide();
} else {
- mx = be->x_root - (windowmenu->getWidth() / 2);
-
- if (be->y <= static_cast<signed>(frame.bevel_w))
- my = frame.rect.y() + frame.title_h;
- else
- my = be->y_root - (windowmenu->getHeight() / 2);
- }
-
- // snap the window menu into a corner if necessary - we check the
- // position of the menu with the coordinates of the client to
- // make the comparisions easier.
- // XXX: this needs some work!
- if (mx > client.rect.right() -
- static_cast<signed>(windowmenu->getWidth()))
- mx = frame.rect.right() - windowmenu->getWidth() - frame.border_w + 1;
- if (mx < client.rect.left())
- mx = frame.rect.x();
-
- if (my > client.rect.bottom() -
- static_cast<signed>(windowmenu->getHeight()))
- my = frame.rect.bottom() - windowmenu->getHeight() - frame.border_w + 1;
- if (my < client.rect.top())
- my = frame.rect.y() + ((decorations & Decor_Titlebar) ?
- frame.title_h : 0);
-
- if (windowmenu) {
- if (! windowmenu->isVisible()) {
- windowmenu->move(mx, my);
- windowmenu->show();
- XRaiseWindow(blackbox->getXDisplay(), windowmenu->getWindowID());
- XRaiseWindow(blackbox->getXDisplay(),
- windowmenu->getSendToMenu()->getWindowID());
- } else {
- windowmenu->hide();
- }
+ int mx = be->x_root - windowmenu->getWidth() / 2,
+ my = be->y_root - windowmenu->getHeight() / 2;
+
+ // snap the window menu into a corner/side if necessary
+ int left_edge, right_edge, top_edge, bottom_edge;
+
+ /*
+ the " + (frame.border_w * 2) - 1" bits are to get the proper width
+ and height of the menu, as the sizes returned by it do not include
+ the borders.
+ */
+ left_edge = frame.rect.x();
+ right_edge = frame.rect.right() -
+ (windowmenu->getWidth() + (frame.border_w * 2) - 1);
+ top_edge = client.rect.top() - (frame.border_w + frame.mwm_border_w);
+ bottom_edge = client.rect.bottom() -
+ (windowmenu->getHeight() + (frame.border_w * 2) - 1) +
+ (frame.border_w + frame.mwm_border_w);
+
+ if (mx < left_edge)
+ mx = left_edge;
+ if (mx > right_edge)
+ mx = right_edge;
+ if (my < top_edge)
+ my = top_edge;
+ if (my > bottom_edge)
+ my = bottom_edge;
+
+ windowmenu->move(mx, my);
+ windowmenu->show();
+ XRaiseWindow(blackbox->getXDisplay(), windowmenu->getWindowID());
+ XRaiseWindow(blackbox->getXDisplay(),
+ windowmenu->getSendToMenu()->getWindowID());
}
// mouse wheel up
} else if (be->button == 4) {
@@ -2768,6 +2792,11 @@ void BlackboxWindow::buttonPressEvent(const XButtonEvent *be) {
void BlackboxWindow::buttonReleaseEvent(const XButtonEvent *re) {
+#ifdef DEBUG
+ fprintf(stderr, "BlackboxWindow::buttonReleaseEvent() for 0x%lx\n",
+ client.window);
+#endif
+
if (re->window == frame.maximize_button) {
if ((re->x >= 0 && re->x <= static_cast<signed>(frame.button_w)) &&
(re->y >= 0 && re->y <= static_cast<signed>(frame.button_w))) {
@@ -2791,9 +2820,6 @@ void BlackboxWindow::buttonReleaseEvent(const XButtonEvent *re) {
endMove();
} else if (flags.resizing) {
endResize();
- } else if (re->window == frame.window) {
- if (re->button == 2 && re->state == Mod1Mask)
- XUngrabPointer(blackbox->getXDisplay(), CurrentTime);
}
}
@@ -3190,6 +3216,11 @@ void BlackboxWindow::endResize(void) {
void BlackboxWindow::motionNotifyEvent(const XMotionEvent *me) {
+#ifdef DEBUG
+ fprintf(stderr, "BlackboxWindow::motionNotifyEvent() for 0x%lx\n",
+ client.window);
+#endif
+
if (flags.moving) {
doMove(me->x_root, me->y_root);
} else if (flags.resizing) {
@@ -3244,6 +3275,9 @@ void BlackboxWindow::restore(bool remap) {
XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask);
XSelectInput(blackbox->getXDisplay(), frame.plate, NoEventMask);
+ // do not leave a shaded window as an icon unless it was an icon
+ if (flags.shaded && ! flags.iconic) setState(NormalState);
+
restoreGravity(client.rect);
XUnmapWindow(blackbox->getXDisplay(), frame.window);
diff --git a/src/Window.hh b/src/Window.hh
index 0f3fb14d..64ad1c34 100644
--- a/src/Window.hh
+++ b/src/Window.hh
@@ -379,7 +379,8 @@ public:
void shade(void);
void stick(void);
void reconfigure(void);
- void updateFocusModel(void);
+ void grabButtons(void);
+ void ungrabButtons(void);
void installColormap(bool install);
void restore(bool remap);
void configure(int dx, int dy, unsigned int dw, unsigned int dh);
@@ -394,7 +395,7 @@ public:
void mapRequestEvent(const XMapRequestEvent *mre);
void unmapNotifyEvent(const XUnmapEvent */*unused*/);
void reparentNotifyEvent(const XReparentEvent */*unused*/);
- void propertyNotifyEvent(Atom atom);
+ void propertyNotifyEvent(const XPropertyEvent *pe);
void exposeEvent(const XExposeEvent *ee);
void configureRequestEvent(const XConfigureRequestEvent *cr);
diff --git a/src/Workspace.cc b/src/Workspace.cc
index 60efba1e..90a83b26 100644
--- a/src/Workspace.cc
+++ b/src/Workspace.cc
@@ -103,8 +103,13 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) {
if ((w->isFocused() || w == lastfocus) &&
! screen->getBlackbox()->doShutdown()) {
BlackboxWindow *newfocus = 0;
- if (w->isTransient())
+ if (w->isTransient()) {
newfocus = w->getTransientFor();
+ if (newfocus &&
+ (newfocus->isIconic() || // do not focus icons
+ newfocus->getWorkspaceNumber() != id)) // or other workspaces
+ newfocus = 0;
+ }
if (! newfocus && ! stackingList.empty())
newfocus = stackingList.front();
@@ -115,7 +120,7 @@ unsigned int Workspace::removeWindow(BlackboxWindow *w) {
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);
} else if (lastfocus == w) {
/*
@@ -320,12 +325,6 @@ void Workspace::reconfigure(void) {
}
-void Workspace::updateFocusModel(void) {
- std::for_each(windowList.begin(), windowList.end(),
- std::mem_fun(&BlackboxWindow::updateFocusModel));
-}
-
-
BlackboxWindow *Workspace::getWindow(unsigned int index) {
if (index < windowList.size()) {
BlackboxWindowList::iterator it = windowList.begin();
diff --git a/src/Workspace.hh b/src/Workspace.hh
index 31ddace8..0059e293 100644
--- a/src/Workspace.hh
+++ b/src/Workspace.hh
@@ -102,7 +102,6 @@ public:
void raiseWindow(BlackboxWindow *w);
void lowerWindow(BlackboxWindow *w);
void reconfigure(void);
- void updateFocusModel(void);
void setCurrent(void);
void setName(const std::string& new_name);
};
diff --git a/src/blackbox.cc b/src/blackbox.cc
index 6af1d2d3..0865b681 100644
--- a/src/blackbox.cc
+++ b/src/blackbox.cc
@@ -322,7 +322,12 @@ void Blackbox::process_event(XEvent *e) {
BlackboxWindow *win = searchWindow(e->xmaprequest.window);
- if (! win) {
+ if (win) {
+ if (win->isIconic()) {
+ win->deiconify();
+ win->setInputFocus();
+ }
+ } else {
BScreen *screen = searchScreen(e->xmaprequest.parent);
if (! screen) {
@@ -444,13 +449,9 @@ void Blackbox::process_event(XEvent *e) {
case PropertyNotify: {
last_time = e->xproperty.time;
- if (e->xproperty.state != PropertyDelete) {
- BlackboxWindow *win = searchWindow(e->xproperty.window);
-
- if (win)
- win->propertyNotifyEvent(e->xproperty.atom);
- }
-
+ BlackboxWindow *win = searchWindow(e->xproperty.window);
+ if (win)
+ win->propertyNotifyEvent(&e->xproperty);
break;
}