#include "Windowmenu.hh"
#include "Workspace.hh"
#include "Slit.hh"
-#include "XAtom.hh"
-#include "Input.hh"
using std::string;
client.window = w;
screen = s;
xatom = blackbox->getXAtom();
- input = blackbox->getInput();
if (! validateClient()) {
delete this;
bool place_window = True;
if (blackbox->isStartup() || isTransient() ||
client.normal_hint_flags & (PPosition|USPosition)) {
- setGravityOffsets();
-
+ applyGravity(frame.rect);
if (blackbox->isStartup() ||
client.rect.intersects(screen->availableArea()))
}
#endif // SHAPE
- grabButtons();
+ 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 (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
window was iconified previously.
*/
- setFocusFlag(False);
+ redrawWindowFrame();
}
positionWindows();
decorate();
- XClearWindow(blackbox->getXDisplay(), frame.window);
- setFocusFlag(flags.focused);
+ redrawWindowFrame();
configure(frame.rect.x(), frame.rect.y(),
frame.rect.width(), frame.rect.height());
}
+void BlackboxWindow::updateFocusModel(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 {
+ blackbox->ungrabButton(Button1, 0, frame.plate);
+ }
+}
+
+
void BlackboxWindow::positionWindows(void) {
XMoveResizeWindow(blackbox->getXDisplay(), frame.window,
frame.rect.x(), frame.rect.y(), frame.inside_w,
(flags.shaded) ? frame.title_h : frame.inside_h);
- XSetWindowBorderWidth(blackbox->getXDisplay(), frame.window, frame.border_w);
+ XSetWindowBorderWidth(blackbox->getXDisplay(), frame.window,
+ frame.border_w);
XSetWindowBorderWidth(blackbox->getXDisplay(), frame.plate,
frame.mwm_border_w);
XMoveResizeWindow(blackbox->getXDisplay(), frame.plate,
num = PropMwmHintsElements;
if (! xatom->getValue(client.window, XAtom::motif_wm_hints,
XAtom::motif_wm_hints, num,
- (unsigned long **)&mwm_hint) ||
- num < PropMwmHintsElements)
+ (unsigned long **)&mwm_hint))
return;
+ if (num < PropMwmHintsElements) {
+ delete [] mwm_hint;
+ return;
+ }
if (mwm_hint->flags & MwmHintsDecorations) {
if (mwm_hint->decorations & MwmDecorAll) {
functions |= Func_Close;
}
}
- delete mwm_hint;
+ delete [] mwm_hint;
}
num = PropBlackboxHintsElements;
if (! xatom->getValue(client.window, XAtom::blackbox_hints,
XAtom::blackbox_hints, num,
- (unsigned long **)&blackbox_hint) ||
- num < PropBlackboxHintsElements)
+ (unsigned long **)&blackbox_hint))
+ return False;
+ if (num < PropBlackboxHintsElements) {
+ delete [] blackbox_hint;
return False;
+ }
if (blackbox_hint->flags & AttribShaded)
flags.shaded = (blackbox_hint->attrib & AttribShaded);
reconfigure();
}
- delete blackbox_hint;
+ delete [] blackbox_hint;
return True;
}
void BlackboxWindow::configure(int dx, int dy,
unsigned int dw, unsigned int dh) {
- bool send_event = (frame.rect.x() != dx || frame.rect.y() != dy);
+ bool send_event = False;
- if ((dw != frame.rect.width()) || (dh != frame.rect.height())) {
+ if (dw != frame.rect.width() || dh != frame.rect.height()) {
frame.rect.setRect(dx, dy, dw, dh);
frame.inside_w = frame.rect.width() - (frame.border_w * 2);
frame.inside_h = frame.rect.height() - (frame.border_w * 2);
positionWindows();
decorate();
- setFocusFlag(flags.focused);
- redrawAllButtons();
- } else {
+ redrawWindowFrame();
+ } else if (frame.rect.x() != dx || frame.rect.y() != dy) {
+ send_event = True;
+
frame.rect.setPos(dx, dy);
XMoveWindow(blackbox->getXDisplay(), frame.window,
frame.rect.x(), frame.rect.y());
-
- if (! flags.moving) send_event = True;
}
if (send_event && ! flags.moving) {
event.xconfigure.above = frame.window;
event.xconfigure.override_redirect = False;
- XSendEvent(blackbox->getXDisplay(), client.window, True,
- NoEventMask, &event);
+ XSendEvent(blackbox->getXDisplay(), client.window, False,
+ StructureNotifyMask, &event);
screen->updateNetizenConfigNotify(&event);
}
return True;
}
- if (! client.rect.intersects(screen->getRect())) {
+ if (! frame.rect.intersects(screen->getRect())) {
// client is outside the screen, move it to the center
configure((screen->getWidth() - frame.rect.width()) / 2,
(screen->getHeight() - frame.rect.height()) / 2,
}
-void BlackboxWindow::deiconify(bool reassoc, bool doraise) {
+void BlackboxWindow::deiconify(bool reassoc, bool raise) {
if (flags.iconic || reassoc)
screen->reassociateWindow(this, BSENTINEL, False);
else if (blackbox_attrib.workspace != screen->getCurrentWorkspace()->getID())
}
}
- if (doraise)
- raise();
-}
-
-
-void BlackboxWindow::raise(void) {
- screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
-}
-
-
-void BlackboxWindow::lower(void) {
- screen->getWorkspace(blackbox_attrib.workspace)->lowerWindow(this);
+ if (raise)
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
}
blackbox_attrib.premax_x = blackbox_attrib.premax_y = 0;
blackbox_attrib.premax_w = blackbox_attrib.premax_h = 0;
- redrawAllButtons();
+ redrawAllButtons(); // in case it is not called in configure()
setState(current_state);
return;
}
const Rect &screen_area = screen->availableArea();
frame.changing = screen_area;
- constrain(TopLeft);
switch(button) {
case 1:
break;
}
+ constrain(TopLeft);
+
if (flags.shaded) {
blackbox_attrib.flags ^= AttribShaded;
blackbox_attrib.attrib ^= AttribShaded;
configure(frame.changing.x(), frame.changing.y(),
frame.changing.width(), frame.changing.height());
if (flags.focused)
- raise();
- redrawAllButtons();
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
+ redrawAllButtons(); // in case it is not called in configure()
setState(current_state);
}
frame.margin.bottom);
} else {
if (! (decorations & Decor_Titlebar))
- return;
+ return; // can't shade it without a titlebar!
XResizeWindow(blackbox->getXDisplay(), frame.window,
frame.inside_w, frame.title_h);
}
-void BlackboxWindow::setFocusFlag(bool focus) {
- // only focus a window if it is visible
- if (focus && !flags.visible)
- return;
-
- flags.focused = focus;
-
+void BlackboxWindow::redrawWindowFrame(void) const {
if (decorations & Decor_Titlebar) {
if (flags.focused) {
if (frame.ftitle)
XSetWindowBorder(blackbox->getXDisplay(),
frame.plate, frame.uborder_pixel);
}
+}
+
+
+void BlackboxWindow::setFocusFlag(bool focus) {
+ // only focus a window if it is visible
+ if (focus && !flags.visible)
+ return;
+
+ flags.focused = focus;
+
+ redrawWindowFrame();
if (screen->isSloppyFocus() && screen->doAutoRaise()) {
if (isFocused()) timer->start();
int i = 0, ncmap = 0;
Colormap *cmaps = XListInstalledColormaps(blackbox->getXDisplay(),
client.window, &ncmap);
- XWindowAttributes wattrib;
if (cmaps) {
+ XWindowAttributes wattrib;
if (XGetWindowAttributes(blackbox->getXDisplay(),
client.window, &wattrib)) {
if (install) {
(unsigned long **)&net))
return;
if (num < PropBlackboxAttributesElements) {
- delete net;
+ delete [] net;
return;
}
blackbox_attrib.premax_h = h;
}
- // with the state set it will then be the map events job to read the window's
- // state and behave accordingly
+ // with the state set it will then be the map event's job to read the
+ // window's state and behave accordingly
- delete net;
+ delete [] net;
}
/*
- * Positions the frame according the the client window position and window
- * gravity.
+ * Positions the Rect r according the the client window position and
+ * window gravity.
*/
-void BlackboxWindow::setGravityOffsets(void) {
- // x coordinates for each gravity type
- const int x_west = client.rect.x();
- const int x_east = client.rect.right() - frame.inside_w + 1;
- const int x_center = client.rect.left() +
- ((client.rect.width() - frame.rect.width()) / 2);
- // y coordinates for each gravity type
- const int y_north = client.rect.y();
- const int y_south = client.rect.bottom() - frame.inside_h + 1;
- const int y_center = client.rect.top() +
- ((client.rect.height() - frame.rect.height()) / 2);
+void BlackboxWindow::applyGravity(Rect &r) {
+ // apply horizontal window gravity
+ switch (client.win_gravity) {
+ default:
+ case NorthWestGravity:
+ case SouthWestGravity:
+ case WestGravity:
+ r.setX(client.rect.x());
+ break;
+ case NorthGravity:
+ case SouthGravity:
+ case CenterGravity:
+ r.setX(client.rect.x() - (frame.margin.left + frame.margin.right) / 2);
+ break;
+
+ case NorthEastGravity:
+ case SouthEastGravity:
+ case EastGravity:
+ r.setX(client.rect.x() - frame.margin.left - frame.margin.right);
+ break;
+
+ case ForgetGravity:
+ case StaticGravity:
+ r.setX(client.rect.x() - frame.margin.left);
+ break;
+ }
+
+ // apply vertical window gravity
switch (client.win_gravity) {
default:
- case NorthWestGravity: frame.rect.setPos(x_west, y_north); break;
- case NorthGravity: frame.rect.setPos(x_center, y_north); break;
- case NorthEastGravity: frame.rect.setPos(x_east, y_north); break;
- case SouthWestGravity: frame.rect.setPos(x_west, y_south); break;
- case SouthGravity: frame.rect.setPos(x_center, y_south); break;
- case SouthEastGravity: frame.rect.setPos(x_east, y_south); break;
- case WestGravity: frame.rect.setPos(x_west, y_center); break;
- case CenterGravity: frame.rect.setPos(x_center, y_center); break;
- case EastGravity: frame.rect.setPos(x_east, y_center); break;
+ case NorthWestGravity:
+ case NorthEastGravity:
+ case NorthGravity:
+ r.setY(client.rect.y());
+ break;
+
+ case CenterGravity:
+ case EastGravity:
+ case WestGravity:
+ r.setY(client.rect.y() - (frame.margin.top + frame.margin.bottom) / 2);
+ break;
+
+ case SouthWestGravity:
+ case SouthEastGravity:
+ case SouthGravity:
+ r.setY(client.rect.y() - frame.margin.top - frame.margin.bottom);
+ break;
case ForgetGravity:
case StaticGravity:
- frame.rect.setPos(client.rect.x() - frame.margin.left,
- client.rect.y() - frame.margin.top);
+ r.setY(client.rect.y() - frame.margin.top);
break;
}
}
/*
- * The reverse of the setGravityOffsets function. Uses the frame window's
- * position to find the window's reference point.
+ * The reverse of the applyGravity function.
+ *
+ * Positions the Rect r according to the frame window position and
+ * window gravity.
*/
-void BlackboxWindow::restoreGravity(void) {
- // x coordinates for each gravity type
- const int x_west = frame.rect.x();
- const int x_east = frame.rect.x() + frame.inside_w - client.rect.width();
- const int x_center = frame.rect.x() -
- ((client.rect.width() - frame.rect.width()) / 2);
- // y coordinates for each gravity type
- const int y_north = frame.rect.y();
- const int y_south = frame.rect.y() + frame.inside_h - client.rect.height();
- const int y_center = frame.rect.y() -
- ((client.rect.height() - frame.rect.height()) / 2);
-
- switch(client.win_gravity) {
+void BlackboxWindow::restoreGravity(Rect &r) {
+ // restore horizontal window gravity
+ switch (client.win_gravity) {
default:
- case NorthWestGravity: client.rect.setPos(x_west, y_north); break;
- case NorthGravity: client.rect.setPos(x_center, y_north); break;
- case NorthEastGravity: client.rect.setPos(x_east, y_north); break;
- case SouthWestGravity: client.rect.setPos(x_west, y_south); break;
- case SouthGravity: client.rect.setPos(x_center, y_south); break;
- case SouthEastGravity: client.rect.setPos(x_east, y_south); break;
- case WestGravity: client.rect.setPos(x_west, y_center); break;
- case CenterGravity: client.rect.setPos(x_center, y_center); break;
- case EastGravity: client.rect.setPos(x_east, y_center); break;
+ case NorthWestGravity:
+ case SouthWestGravity:
+ case WestGravity:
+ r.setX(frame.rect.x());
+ break;
+
+ case NorthGravity:
+ case SouthGravity:
+ case CenterGravity:
+ r.setX(frame.rect.x() + (frame.margin.left + frame.margin.right) / 2);
+ break;
+
+ case NorthEastGravity:
+ case SouthEastGravity:
+ case EastGravity:
+ r.setX(frame.rect.x() + frame.margin.left + frame.margin.right);
+ break;
case ForgetGravity:
case StaticGravity:
- client.rect.setPos(frame.rect.left() + frame.margin.left,
- frame.rect.top() + frame.margin.top);
+ r.setX(frame.rect.x() + frame.margin.left);
+ break;
+ }
+
+ // restore vertical window gravity
+ switch (client.win_gravity) {
+ default:
+ case NorthWestGravity:
+ case NorthEastGravity:
+ case NorthGravity:
+ r.setY(frame.rect.y());
+ break;
+
+ case CenterGravity:
+ case EastGravity:
+ case WestGravity:
+ r.setY(frame.rect.y() + (frame.margin.top + frame.margin.bottom) / 2);
+ break;
+
+ case SouthWestGravity:
+ case SouthEastGravity:
+ case SouthGravity:
+ r.setY(frame.rect.y() + frame.margin.top + frame.margin.bottom);
+ break;
+
+ case ForgetGravity:
+ case StaticGravity:
+ r.setY(frame.rect.y() + frame.margin.top);
break;
}
}
-void BlackboxWindow::redrawLabel(void) {
+void BlackboxWindow::redrawLabel(void) const {
if (flags.focused) {
if (frame.flabel)
XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
}
-void BlackboxWindow::redrawAllButtons(void) {
+void BlackboxWindow::redrawAllButtons(void) const {
if (frame.iconify_button) redrawIconifyButton(False);
if (frame.maximize_button) redrawMaximizeButton(flags.maximized);
if (frame.close_button) redrawCloseButton(False);
}
-void BlackboxWindow::redrawIconifyButton(bool pressed) {
+void BlackboxWindow::redrawIconifyButton(bool pressed) const {
if (! pressed) {
if (flags.focused) {
if (frame.fbutton)
}
-void BlackboxWindow::redrawMaximizeButton(bool pressed) {
+void BlackboxWindow::redrawMaximizeButton(bool pressed) const {
if (! pressed) {
if (flags.focused) {
if (frame.fbutton)
}
-void BlackboxWindow::redrawCloseButton(bool pressed) {
+void BlackboxWindow::redrawCloseButton(bool pressed) const {
if (! pressed) {
if (flags.focused) {
if (frame.fbutton)
case ZoomState:
default:
show();
- raise();
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
if (! blackbox->isStartup() && (isTransient() || screen->doFocusNew())) {
XSync(blackbox->getXDisplay(), False); // make sure the frame is mapped..
setInputFocus();
if (cr->window != client.window || flags.iconic)
return;
- int cx = frame.rect.x(), cy = frame.rect.y();
- unsigned int cw = frame.rect.width(), ch = frame.rect.height();
-
if (cr->value_mask & CWBorderWidth)
client.old_bw = cr->border_width;
- if (cr->value_mask & CWX)
- cx = cr->x - frame.margin.left;
+ if (cr->value_mask & (CWX | CWY | CWWidth | CWHeight)) {
+ Rect req = frame.rect;
+
+ if (cr->value_mask & (CWX | CWY)) {
+ if (cr->value_mask & CWX)
+ client.rect.setX(cr->x);
+ if (cr->value_mask & CWY)
+ client.rect.setY(cr->y);
- if (cr->value_mask & CWY)
- cy = cr->y - frame.margin.top;
+ applyGravity(req);
+ }
- if (cr->value_mask & CWWidth)
- cw = cr->width + frame.margin.left + frame.margin.right;
+ if (cr->value_mask & CWWidth)
+ req.setWidth(cr->width + frame.margin.left + frame.margin.right);
- if (cr->value_mask & CWHeight)
- ch = cr->height + frame.margin.top + frame.margin.bottom;
+ if (cr->value_mask & CWHeight)
+ req.setHeight(cr->height + frame.margin.top + frame.margin.bottom);
- if (frame.rect != Rect(cx, cy, cw, ch))
- configure(cx, cy, cw, ch);
+ configure(req.x(), req.y(), req.width(), req.height());
+ }
if (cr->value_mask & CWStackMode) {
switch (cr->detail) {
case Below:
case BottomIf:
- lower();
+ screen->getWorkspace(blackbox_attrib.workspace)->lowerWindow(this);
break;
case Above:
case TopIf:
default:
- raise();
- break;
- }
- }
-}
-
-
-void BlackboxWindow::grabButtons(void) {
- const BInput::MouseBindingList &mbindings = input->getMouseBindings();
-
- BInput::MouseBindingList::const_iterator mit = mbindings.begin();
- const BInput::MouseBindingList::const_iterator mend = mbindings.end();
- for (; mit != mend; ++mit) {
- // dont grab for an action the window can't perform
- //if (! (mit->action == BInput::BeginMove && functions & Func_Move) &&
- // ! (mit->action == BInput::BeginResize && functions & Func_Resize)) {
- switch (mit->event) {
- case BInput::WindowClientPress:
- blackbox->grabButton(mit->button, mit->state, frame.plate, True,
- ButtonPressMask, GrabModeSync, GrabModeSync,
- frame.plate, None);
- break;
- case BInput::WindowDrag:
- blackbox->grabButton(mit->button, mit->state, frame.window, True,
- ButtonMotionMask, GrabModeAsync, GrabModeAsync,
- frame.window, None);
- default:
- break;
- }
- }
-}
-
-
-void BlackboxWindow::ungrabButtons(void) {
- const BInput::MouseBindingList &mbindings = input->getMouseBindings();
-
- BInput::MouseBindingList::const_iterator mit = mbindings.begin();
- const BInput::MouseBindingList::const_iterator mend = mbindings.end();
- for (; mit != mend; ++mit) {
- switch (mit->event) {
- case BInput::WindowClientPress:
- blackbox->ungrabButton(mit->button, mit->state, frame.plate);
- break;
- case BInput::WindowDrag:
- blackbox->ungrabButton(mit->button, mit->state, frame.window);
- default:
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
break;
}
}
void BlackboxWindow::buttonPressEvent(const XButtonEvent *be) {
- if (windowmenu && windowmenu->isVisible()) windowmenu->hide();
-
if (frame.maximize_button == be->window) {
- if (input->hasAction(be->button, be->state, BInput::MaximizeButtonClick))
- redrawMaximizeButton(True);
- } else if (frame.iconify_button == be->window) {
- if (input->hasAction(be->button, be->state, BInput::IconifyButtonClick))
+ redrawMaximizeButton(True);
+ } else if (be->button == 1 || (be->button == 3 && be->state == Mod1Mask)) {
+ if (! flags.focused)
+ setInputFocus();
+
+ if (frame.iconify_button == be->window) {
redrawIconifyButton(True);
- } else if (frame.close_button == be->window) {
- if (input->hasAction(be->button, be->state, BInput::CloseButtonClick))
+ } else if (frame.close_button == be->window) {
redrawCloseButton(True);
- } else if (frame.title == be->window || frame.label == be->window) {
- if (be->time - lastButtonPressTime <= blackbox->getDoubleClickInterval()) {
- lastButtonPressTime = 0;
- input->doAction(this, be->button, be->state,
- BInput::WindowTitleDoublePress);
- } else {
- lastButtonPressTime = be->time;
- input->doAction(this, be->button, be->state,
- BInput::WindowTitlePress);
- }
- } else if (frame.plate == be->window) {
- input->doAction(this, be->button, be->state, BInput::WindowClientPress);
- // buttons on the client window are grabbed in Sync mode, so we need to let
- // events back through again
- XAllowEvents(blackbox->getXDisplay(), ReplayPointer, be->time);
- } else if (frame.window == be->window || frame.handle == be->window) {
- input->doAction(this, be->button, be->state, BInput::WindowFramePress);
- }
-}
+ } else if (frame.plate == be->window) {
+ if (windowmenu && windowmenu->isVisible()) windowmenu->hide();
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
-void BlackboxWindow::showWindowMenu(int root_x, int root_y) {
- if (! windowmenu || windowmenu->isVisible())
- return;
-
- root_x -= windowmenu->getWidth() / 2;
- root_y -= windowmenu->getHeight() / 2;
+ XAllowEvents(blackbox->getXDisplay(), ReplayPointer, be->time);
+ } else {
+ if (frame.title == be->window || frame.label == be->window) {
+ if (((be->time - lastButtonPressTime) <=
+ blackbox->getDoubleClickInterval()) ||
+ (be->state & ControlMask)) {
+ lastButtonPressTime = 0;
+ shade();
+ } else {
+ lastButtonPressTime = be->time;
+ }
+ }
- // snap the window menu into a corner/side if necessary
- int left_edge, right_edge, top_edge, bottom_edge;
-
- left_edge = frame.rect.x();
- right_edge = frame.rect.right() - windowmenu->getWidth() - frame.border_w - 1;
- if (decorations & Decor_Titlebar)
- top_edge = frame.rect.y() + frame.title_h + frame.border_w;
- else
- top_edge = frame.rect.y() + frame.border_w;
- if (decorations & Decor_Handle)
- bottom_edge = frame.rect.bottom() - frame.handle_h - (frame.border_w * 3) -
- windowmenu->getHeight();
- else
- bottom_edge = frame.rect.bottom() - windowmenu->getHeight() -
- frame.border_w + 1;
-
- if (root_x > right_edge)
- root_x = right_edge;
- if (root_x < left_edge)
- root_x = left_edge;
+ if (windowmenu && windowmenu->isVisible()) windowmenu->hide();
- if (root_y > bottom_edge)
- root_y = bottom_edge;
- if (root_y < top_edge)
- root_y = top_edge;
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
+ }
+ } else if (be->button == 2 && (be->window != frame.iconify_button) &&
+ (be->window != frame.close_button)) {
+ screen->getWorkspace(blackbox_attrib.workspace)->lowerWindow(this);
+ } 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();
+ } 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);
+ }
- windowmenu->move(root_x, root_y);
- windowmenu->show();
- XRaiseWindow(blackbox->getXDisplay(), windowmenu->getWindowID());
- XRaiseWindow(blackbox->getXDisplay(),
- windowmenu->getSendToMenu()->getWindowID());
+ // 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();
+ }
+ }
+ // mouse wheel up
+ } else if (be->button == 4) {
+ if ((be->window == frame.label ||
+ be->window == frame.title) &&
+ ! flags.shaded)
+ shade();
+ // mouse wheel down
+ } else if (be->button == 5) {
+ if ((be->window == frame.label ||
+ be->window == frame.title) &&
+ flags.shaded)
+ shade();
+ }
}
void BlackboxWindow::buttonReleaseEvent(const XButtonEvent *re) {
- // get the proper state, without the button that was released
- unsigned int state;
- switch (re->button) {
- case Button1:
- state = re->state & ~Button1Mask;
- break;
- case Button2:
- state = re->state & ~Button2Mask;
- break;
- case Button3:
- state = re->state & ~Button3Mask;
- break;
- case Button4:
- state = re->state & ~Button4Mask;
- break;
- case Button5:
- state = re->state & ~Button5Mask;
- break;
- default:
- assert(false); // unhandled button
- }
-
- if (frame.maximize_button == re->window) {
- if ((re->x < 0 || re->x >= static_cast<signed>(frame.button_w)) ||
- (re->y < 0 || re->y >= static_cast<signed>(frame.button_w)) ||
- ! input->doAction(this, re->button, state,
- BInput::MaximizeButtonClick))
+ 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))) {
+ maximize(re->button);
+ } else {
redrawMaximizeButton(flags.maximized);
- } else if (frame.iconify_button == re->window) {
- if ((re->x < 0 || re->x >= static_cast<signed>(frame.button_w)) ||
- (re->y < 0 || re->y >= static_cast<signed>(frame.button_w)) ||
- ! input->doAction(this, re->button, state,
- BInput::IconifyButtonClick))
+ }
+ } else if (re->window == frame.iconify_button) {
+ if ((re->x >= 0 && re->x <= static_cast<signed>(frame.button_w)) &&
+ (re->y >= 0 && re->y <= static_cast<signed>(frame.button_w))) {
+ iconify();
+ } else {
redrawIconifyButton(False);
- } else if (frame.close_button == re->window) {
- if ((re->x < 0 || re->x >= static_cast<signed>(frame.button_w)) ||
- (re->y < 0 || re->y >= static_cast<signed>(frame.button_w)))
- input->doAction(this, re->button, state, BInput::CloseButtonClick);
- redrawCloseButton(False);
+ }
+ } else if (re->window == frame.close_button) {
+ if ((re->x >= 0 && re->x <= static_cast<signed>(frame.button_w)) &&
+ (re->y >= 0 && re->y <= static_cast<signed>(frame.button_w)))
+ close();
+ redrawCloseButton(False);
} else if (flags.moving) {
endMove();
} else if (flags.resizing) {
endResize();
+ } else if (re->window == frame.window) {
+ if (re->button == 2 && re->state == Mod1Mask)
+ XUngrabPointer(blackbox->getXDisplay(), CurrentTime);
}
}
-void BlackboxWindow::motionNotifyEvent(const XMotionEvent *me) {
- // get the button that is being used
- // get the proper state, without the button that is being used
- unsigned int button;
- unsigned int state;
- if (me->state & Button1Mask) {
- button = Button1;
- state = me->state & ~Button1Mask;
- } else if (me->state & Button2Mask) {
- button = Button2;
- state = me->state & ~Button2Mask;
- } else if (me->state & Button3Mask) {
- button = Button3;
- state = me->state & ~Button3Mask;
- } else if (me->state & Button4Mask) {
- button = Button4;
- state = me->state & ~Button4Mask;
- } else if (me->state & Button5Mask) {
- button = Button5;
- state = me->state & ~Button5Mask;
- } else {
- return;
- }
-
- if (flags.moving) {
- doMove(me->x_root, me->y_root);
- } else if (flags.resizing) {
- doResize(me->x_root, me->y_root);
- } else {
- if (frame.title == me->window || frame.label == me->window)
- input->doAction(this, button, state, BInput::WindowTitleDrag);
- else if (frame.handle == me->window)
- input->doAction(this, button, state, BInput::WindowHandleDrag);
- else if (frame.left_grip == me->window)
- input->doAction(this, button, state, BInput::WindowLeftGripDrag);
- else if (frame.right_grip == me->window)
- input->doAction(this, button, state, BInput::WindowRightGripDrag);
- else if (frame.window == me->window)
- input->doAction(this, button, state, BInput::WindowDrag);
- }
-}
-
void BlackboxWindow::beginMove(int x_root, int y_root) {
assert(! (flags.resizing || flags.moving));
}
+void BlackboxWindow::motionNotifyEvent(const XMotionEvent *me) {
+ if (flags.moving) {
+ doMove(me->x_root, me->y_root);
+ } else if (flags.resizing) {
+ doResize(me->x_root, me->y_root);
+ } else {
+ if (! flags.resizing && (me->state & Button1Mask) &&
+ (functions & Func_Move) &&
+ (frame.title == me->window || frame.label == me->window ||
+ frame.handle == me->window || frame.window == me->window)) {
+ beginMove(me->x_root, me->y_root);
+ } else if ((functions & Func_Resize) &&
+ (((me->state & Button1Mask) &&
+ (me->window == frame.right_grip ||
+ me->window == frame.left_grip)) ||
+ (me->state & (Mod1Mask | Button3Mask) &&
+ me->window == frame.window))) {
+ beginResize(me->x_root, me->y_root,
+ (me->window == frame.left_grip) ? BottomLeft : BottomRight);
+ }
+ }
+}
+
+
#ifdef SHAPE
void BlackboxWindow::shapeEvent(XShapeEvent *) {
if (blackbox->hasShapeExtensions() && flags.shaped) {
XSelectInput(blackbox->getXDisplay(), client.window, NoEventMask);
XSelectInput(blackbox->getXDisplay(), frame.plate, NoEventMask);
- restoreGravity();
+ restoreGravity(client.rect);
XUnmapWindow(blackbox->getXDisplay(), frame.window);
XUnmapWindow(blackbox->getXDisplay(), client.window);
// timer for autoraise
void BlackboxWindow::timeout(void) {
- raise();
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
}
withdraw();
} else {
show();
- raise();
+ screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
}
}
if (flags.shaded && ! (decorations & Decor_Titlebar))
shade();
- if (frame.window) {
+ if (flags.visible && frame.window) {
XMapSubwindows(blackbox->getXDisplay(), frame.window);
XMapWindow(blackbox->getXDisplay(), frame.window);
}
dh -= base_height;
dh /= client.height_inc;
- if (pw) *pw = dw;
- if (ph) *ph = dh;
+ if (pw) {
+ if (client.width_inc == 1)
+ *pw = dw + base_width;
+ else
+ *pw = dw;
+ }
+ if (ph) {
+ if (client.height_inc == 1)
+ *ph = dh + base_height;
+ else
+ *ph = dh;
+ }
dw *= client.width_inc;
dw += base_width;