X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FWindow.cc;h=ec042c305ae77e80cb253bdddbb40d7f9ed4afd7;hb=eb8a11a5a7b066ada63cc3550f8314f53eaf1a39;hp=f768f6c15e90ad088401ce6071e1b7055c04535d;hpb=6a36505f8aa312ee2ccf0f173bc0fc6659664418;p=chaz%2Fopenbox diff --git a/src/Window.cc b/src/Window.cc index f768f6c1..ec042c30 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -216,7 +216,7 @@ OpenboxWindow::OpenboxWindow(Openbox &o, Window w, BScreen *s) : openbox(o) { } upsize(); - Bool place_window = True; + place_window = true; if (openbox.isStartup() || flags.transient || client.normal_hint_flags & (PPosition|USPosition)) { setGravityOffsets(); @@ -226,7 +226,7 @@ OpenboxWindow::OpenboxWindow(Openbox &o, Window w, BScreen *s) : openbox(o) { (signed) (frame.y + frame.y_border) >= 0 && frame.x <= (signed) screen->size().w() && frame.y <= (signed) screen->size().h())) - place_window = False; + place_window = false; } frame.window = createToplevelWindow(frame.x, frame.y, frame.width, @@ -1385,12 +1385,12 @@ Bool OpenboxWindow::setInputFocus(void) { } else if (! flags.focused) { if (focus_mode == F_LocallyActive || focus_mode == F_Passive) XSetInputFocus(display, client.window, - RevertToPointerRoot, CurrentTime); + RevertToPointerRoot, CurrentTime); else XSetInputFocus(display, screen->getRootWindow(), RevertToNone, CurrentTime); - openbox.setFocusedWindow(this); + openbox.focusWindow(this); if (flags.send_focus_message) { XEvent ce; @@ -1422,6 +1422,9 @@ Bool OpenboxWindow::setInputFocus(void) { void OpenboxWindow::iconify(void) { if (flags.iconic) return; + if (flags.moving) + endMove(); + if (windowmenu) windowmenu->hide(); setState(IconicState); @@ -1449,7 +1452,7 @@ void OpenboxWindow::iconify(void) { } -void OpenboxWindow::deiconify(Bool reassoc, Bool raise) { +void OpenboxWindow::deiconify(bool reassoc, bool raise, bool initial) { if (flags.iconic || reassoc) screen->reassociateWindow(this, -1, False); else if (workspace_number != screen->getCurrentWorkspace()->getWorkspaceID()) @@ -1465,6 +1468,18 @@ void OpenboxWindow::deiconify(Bool reassoc, Bool raise) { XMapSubwindows(display, frame.window); XMapWindow(display, frame.window); + // if we're using the click to place placement type, then immediately + // after the window is mapped, we need to start interactively moving it + if (initial && place_window && + screen->placementPolicy() == BScreen::ClickMousePlacement) { + int x, y, rx, ry; + Window c, r; + unsigned int m; + XQueryPointer(openbox.getXDisplay(), screen->getRootWindow(), + &r, &c, &rx, &ry, &x, &y, &m); + startMove(rx, ry); + } + if (flags.iconic && screen->focusNew()) setInputFocus(); flags.visible = True; @@ -1494,6 +1509,9 @@ void OpenboxWindow::close(void) { void OpenboxWindow::withdraw(void) { + if (flags.moving) + endMove(); + flags.visible = False; flags.iconic = False; @@ -1509,6 +1527,9 @@ void OpenboxWindow::withdraw(void) { void OpenboxWindow::maximize(unsigned int button) { + if (flags.moving) + endMove(); + // handle case where menu is open then the max button is used instead if (windowmenu && windowmenu->isVisible()) windowmenu->hide(); @@ -1533,111 +1554,12 @@ void OpenboxWindow::maximize(unsigned int button) { return; } - // the following code is temporary and will be taken care of by Screen in the - // future (with the NETWM 'strut') - Rect space(0, 0, screen->size().w(), screen->size().h()); - if (! screen->fullMax()) { -#ifdef SLIT - Slit *slit = screen->getSlit(); - int slit_x = slit->autoHide() ? slit->hiddenOrigin().x() : slit->area().x(), - slit_y = slit->autoHide() ? slit->hiddenOrigin().y() : slit->area().y(); - Toolbar *toolbar = screen->getToolbar(); - int tbarh = screen->hideToolbar() ? 0 : - toolbar->getExposedHeight() + screen->getBorderWidth() * 2; - bool tbartop; - switch (toolbar->placement()) { - case Toolbar::TopLeft: - case Toolbar::TopCenter: - case Toolbar::TopRight: - tbartop = true; - break; - case Toolbar::BottomLeft: - case Toolbar::BottomCenter: - case Toolbar::BottomRight: - tbartop = false; - break; - default: - ASSERT(false); // unhandled placement - } - if ((slit->direction() == Slit::Horizontal && - (slit->placement() == Slit::TopLeft || - slit->placement() == Slit::TopRight)) || - slit->placement() == Slit::TopCenter) { - // exclude top - if (tbartop && slit_y + slit->area().h() < tbarh) { - space.setY(space.y() + tbarh); - space.setH(space.h() - tbarh); - } else { - space.setY(space.y() + (slit_y + slit->area().h() + - screen->getBorderWidth() * 2)); - space.setH(space.h() - (slit_y + slit->area().h() + - screen->getBorderWidth() * 2)); - if (!tbartop) - space.setH(space.h() - tbarh); - } - } else if ((slit->direction() == Slit::Vertical && - (slit->placement() == Slit::TopRight || - slit->placement() == Slit::BottomRight)) || - slit->placement() == Slit::CenterRight) { - // exclude right - space.setW(space.w() - (screen->size().w() - slit_x)); - if (tbartop) - space.setY(space.y() + tbarh); - space.setH(space.h() - tbarh); - } else if ((slit->direction() == Slit::Horizontal && - (slit->placement() == Slit::BottomLeft || - slit->placement() == Slit::BottomRight)) || - slit->placement() == Slit::BottomCenter) { - // exclude bottom - if (!tbartop && (screen->size().h() - slit_y) < tbarh) { - space.setH(space.h() - tbarh); - } else { - space.setH(space.h() - (screen->size().h() - slit_y)); - if (tbartop) { - space.setY(space.y() + tbarh); - space.setH(space.h() - tbarh); - } - } - } else {// if ((slit->direction() == Slit::Vertical && - // (slit->placement() == Slit::TopLeft || - // slit->placement() == Slit::BottomLeft)) || - // slit->placement() == Slit::CenterLeft) - // exclude left - space.setX(slit_x + slit->area().w() + - screen->getBorderWidth() * 2); - space.setW(space.w() - (slit_x + slit->area().w() + - screen->getBorderWidth() * 2)); - if (tbartop) - space.setY(space.y() + tbarh); - space.setH(space.h() - tbarh); - } -#else // !SLIT - Toolbar *toolbar = screen->getToolbar(); - int tbarh = screen->hideToolbar() ? 0 : - toolbar->getExposedHeight() + screen->getBorderWidth() * 2; - switch (toolbar->placement()) { - case Toolbar::TopLeft: - case Toolbar::TopCenter: - case Toolbar::TopRight: - space.setY(toolbar->getExposedHeight()); - space.setH(space.h() - toolbar->getExposedHeight()); - break; - case Toolbar::BottomLeft: - case Toolbar::BottomCenter: - case Toolbar::BottomRight: - space.setH(space.h() - tbarh); - break; - default: - ASSERT(false); // unhandled placement - } -#endif // SLIT - } - openbox_attrib.premax_x = frame.x; openbox_attrib.premax_y = frame.y; openbox_attrib.premax_w = frame.width; openbox_attrib.premax_h = frame.height; + Rect space = screen->availableArea(); unsigned int dw = space.w(), dh = space.h(); dw -= frame.border_w * 2; @@ -1821,6 +1743,7 @@ void OpenboxWindow::setFocusFlag(Bool focus) { if (screen->sloppyFocus() && screen->autoRaise() && timer->isTiming()) timer->stop(); + } @@ -2316,7 +2239,8 @@ void OpenboxWindow::mapRequestEvent(XMapRequestEvent *re) { case InactiveState: case ZoomState: default: - deiconify(False); + deiconify(False, True, True); // specify that we're initializing the + // window break; } @@ -2361,6 +2285,9 @@ void OpenboxWindow::unmapNotifyEvent(XUnmapEvent *ue) { openbox.grab(); if (! validateClient()) return; + if (flags.moving) + endMove(); + XChangeSaveSet(display, client.window, SetModeDelete); XSelectInput(display, client.window, NoEventMask); @@ -2396,6 +2323,8 @@ void OpenboxWindow::unmapNotifyEvent(XUnmapEvent *ue) { void OpenboxWindow::destroyNotifyEvent(XDestroyWindowEvent *de) { if (de->window == client.window) { + if (flags.moving) + endMove(); XUnmapWindow(display, frame.window); delete this; @@ -2582,8 +2511,6 @@ void OpenboxWindow::buttonPressEvent(XButtonEvent *be) { // alt + left/right click begins interactively moving/resizing the window // when the mouse is moved if (be->state == Mod1Mask && (be->button == 1 || be->button == 3)) { - frame.grab_x = be->x_root - frame.x - frame.border_w; - frame.grab_y = be->y_root - frame.y - frame.border_w; if (be->button == 3) { if (screen->getWindowZones() == 4 && be->y < (signed) frame.height / 2) { @@ -2672,7 +2599,7 @@ void OpenboxWindow::buttonPressEvent(XButtonEvent *be) { mx = be->x_root - windowmenu->getWidth() / 2; if (be->window == frame.title || be->window == frame.label) { my = frame.y + frame.title_h; - } else if (be->window = frame.handle) { + } else if (be->window == frame.handle) { my = frame.y + frame.y_handle - windowmenu->getHeight(); } else { // (be->window == frame.window) if (be->y <= (signed) frame.bevel_w) { @@ -2798,21 +2725,7 @@ void OpenboxWindow::buttonReleaseEvent(XButtonEvent *re) { // when the window is being interactively moved, a button release stops the // move where it is if (flags.moving) { - flags.moving = False; - - openbox.maskWindowEvents(0, (OpenboxWindow *) 0); - if (!screen->opaqueMove()) { - XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), - frame.move_x, frame.move_y, frame.resize_w - 1, - frame.resize_h - 1); - - configure(frame.move_x, frame.move_y, frame.width, frame.height); - openbox.ungrab(); - } else { - configure(frame.x, frame.y, frame.width, frame.height); - } - screen->hideGeometry(); - XUngrabPointer(display, CurrentTime); + endMove(); // when the window is being interactively resized, a button release stops the // resizing } else if (flags.resizing) { @@ -2844,105 +2757,149 @@ void OpenboxWindow::buttonReleaseEvent(XButtonEvent *re) { } -void OpenboxWindow::motionNotifyEvent(XMotionEvent *me) { - if (!flags.resizing && (me->state & Button1Mask) && functions.move && - (frame.title == me->window || frame.label == me->window || - frame.handle == me->window || frame.window == me->window)) { - if (! flags.moving) { - XGrabPointer(display, me->window, False, Button1MotionMask | - ButtonReleaseMask, GrabModeAsync, GrabModeAsync, - None, openbox.getMoveCursor(), CurrentTime); +void OpenboxWindow::startMove(int x, int y) { + ASSERT(!flags.moving); - if (windowmenu && windowmenu->isVisible()) - windowmenu->hide(); + // make sure only one window is moving at a time + OpenboxWindow *w = openbox.getMaskedWindow(); + if (w != (OpenboxWindow *) 0 && w->flags.moving) + w->endMove(); + + XGrabPointer(display, frame.window, False, PointerMotionMask | + ButtonReleaseMask, GrabModeAsync, GrabModeAsync, + None, openbox.getMoveCursor(), CurrentTime); - flags.moving = True; + if (windowmenu && windowmenu->isVisible()) + windowmenu->hide(); - openbox.maskWindowEvents(client.window, this); + flags.moving = True; - if (! screen->opaqueMove()) { - openbox.grab(); + openbox.maskWindowEvents(client.window, this); - frame.move_x = frame.x; - frame.move_y = frame.y; - frame.resize_w = frame.width + (frame.border_w * 2); - frame.resize_h = ((flags.shaded) ? frame.title_h : frame.height) + - (frame.border_w * 2); + if (! screen->opaqueMove()) { + openbox.grab(); - screen->showPosition(frame.x, frame.y); + frame.move_x = frame.x; + frame.move_y = frame.y; + frame.resize_w = frame.width + (frame.border_w * 2); + frame.resize_h = ((flags.shaded) ? frame.title_h : frame.height) + + (frame.border_w * 2); - XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), - frame.move_x, frame.move_y, - frame.resize_w - 1, frame.resize_h - 1); - } - } else { - int dx = me->x_root - frame.grab_x, dy = me->y_root - frame.grab_y; - - dx -= frame.border_w; - dy -= frame.border_w; - - int snap_distance = screen->edgeSnapThreshold(); - // width/height of the snapping window - unsigned int snap_w = frame.width + (frame.border_w * 2); - unsigned int snap_h = area().h() + (frame.border_w * 2); - if (snap_distance) { - int drx = screen->size().w() - (dx + snap_w); - - if (dx < drx && (dx > 0 && dx < snap_distance) || - (dx < 0 && dx > -snap_distance) ) - dx = 0; - else if ( (drx > 0 && drx < snap_distance) || - (drx < 0 && drx > -snap_distance) ) - dx = screen->size().w() - snap_w; - - int dtty, dbby, dty, dby; - switch (screen->getToolbar()->placement()) { - case Toolbar::TopLeft: - case Toolbar::TopCenter: - case Toolbar::TopRight: - dtty = screen->getToolbar()->getExposedHeight() + - frame.border_w; - dbby = screen->size().h(); - break; - - default: - dtty = 0; - dbby = screen->getToolbar()->area().y(); - break; - } + screen->showPosition(frame.x, frame.y); - dty = dy - dtty; - dby = dbby - (dy + snap_h); + XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), + frame.move_x, frame.move_y, + frame.resize_w - 1, frame.resize_h - 1); + } + frame.grab_x = x - frame.x - frame.border_w; + frame.grab_y = y - frame.y - frame.border_w; +} - if ( (dy > 0 && dty < snap_distance) || - (dy < 0 && dty > -snap_distance) ) - dy = dtty; - else if ( (dby > 0 && dby < snap_distance) || - (dby < 0 && dby > -snap_distance) ) - dy = dbby - snap_h; - } - if (screen->opaqueMove()) { - configure(dx, dy, frame.width, frame.height); - } else { - XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), - frame.move_x, frame.move_y, frame.resize_w - 1, - frame.resize_h - 1); +void OpenboxWindow::doMove(int x, int y) { + ASSERT(flags.moving); - frame.move_x = dx; - frame.move_y = dy; + int dx = x - frame.grab_x, dy = y - frame.grab_y; - XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), - frame.move_x, frame.move_y, frame.resize_w - 1, - frame.resize_h - 1); - } + dx -= frame.border_w; + dy -= frame.border_w; + + int snap_distance = screen->edgeSnapThreshold(); + // width/height of the snapping window + unsigned int snap_w = frame.width + (frame.border_w * 2); + unsigned int snap_h = area().h() + (frame.border_w * 2); + if (snap_distance) { + int drx = screen->size().w() - (dx + snap_w); + + if (dx < drx && (dx > 0 && dx < snap_distance) || + (dx < 0 && dx > -snap_distance) ) + dx = 0; + else if ( (drx > 0 && drx < snap_distance) || + (drx < 0 && drx > -snap_distance) ) + dx = screen->size().w() - snap_w; + + int dtty, dbby, dty, dby; + switch (screen->getToolbar()->placement()) { + case Toolbar::TopLeft: + case Toolbar::TopCenter: + case Toolbar::TopRight: + dtty = screen->getToolbar()->getExposedHeight() + + frame.border_w; + dbby = screen->size().h(); + break; - screen->showPosition(dx, dy); + default: + dtty = 0; + dbby = screen->getToolbar()->area().y(); + break; } - } else if (functions.resize && + + dty = dy - dtty; + dby = dbby - (dy + snap_h); + + if ( (dy > 0 && dty < snap_distance) || + (dy < 0 && dty > -snap_distance) ) + dy = dtty; + else if ( (dby > 0 && dby < snap_distance) || + (dby < 0 && dby > -snap_distance) ) + dy = dbby - snap_h; + } + + if (screen->opaqueMove()) { + configure(dx, dy, frame.width, frame.height); + } else { + XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), + frame.move_x, frame.move_y, frame.resize_w - 1, + frame.resize_h - 1); + + frame.move_x = dx; + frame.move_y = dy; + + XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), + frame.move_x, frame.move_y, frame.resize_w - 1, + frame.resize_h - 1); + } + + screen->showPosition(dx, dy); +} + + +void OpenboxWindow::endMove() { + ASSERT(flags.moving); + + flags.moving = False; + + openbox.maskWindowEvents(0, (OpenboxWindow *) 0); + if (!screen->opaqueMove()) { + XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), + frame.move_x, frame.move_y, frame.resize_w - 1, + frame.resize_h - 1); + + configure(frame.move_x, frame.move_y, frame.width, frame.height); + openbox.ungrab(); + } else { + configure(frame.x, frame.y, frame.width, frame.height); + } + screen->hideGeometry(); + XUngrabPointer(display, CurrentTime); + // if there are any left over motions from the move, drop them now cuz they + // cause problems + XEvent e; + while (XCheckTypedWindowEvent(display, frame.window, MotionNotify, &e)); +} + + +void OpenboxWindow::motionNotifyEvent(XMotionEvent *me) { + if (flags.moving) + doMove(me->x_root, me->y_root); + else if (!flags.resizing && (me->state & Button1Mask) && functions.move && + (frame.title == me->window || frame.label == me->window || + frame.handle == me->window || frame.window == me->window)) + startMove(me->x_root, me->y_root); + else if (functions.resize && (((me->state & Button1Mask) && (me->window == frame.right_grip || me->window == frame.left_grip)) || - (me->state & (Mod1Mask | Button3Mask) && + (me->state == (Mod1Mask | Button3Mask) && me->window == frame.window))) { Bool left = resize_zone & ZoneLeft; @@ -3089,6 +3046,8 @@ void OpenboxWindow::restore(void) { XMapWindow(display, client.window); XFlush(display); + + delete this; } @@ -3146,21 +3105,25 @@ void OpenboxWindow::changeOpenboxHints(OpenboxHints *net) { default: case DecorNormal: - decorations.titlebar = decorations.border = decorations.handle = - decorations.iconify = decorations.maximize = decorations.menu = True; + decorations.titlebar = decorations.iconify = decorations.menu = + decorations.border = True; + decorations.handle = (functions.resize && !flags.transient); + decorations.maximize = functions.maximize; break; case DecorTiny: decorations.titlebar = decorations.iconify = decorations.menu = True; - decorations.border = decorations.handle = decorations.maximize = False; - + decorations.border = decorations.border = decorations.handle = False; + decorations.maximize = functions.maximize; + break; case DecorTool: - decorations.titlebar = decorations.menu = functions.move = True; - decorations.iconify = decorations.border = decorations.handle = - decorations.maximize = False; + decorations.titlebar = decorations.menu = True; + decorations.iconify = decorations.border = False; + decorations.handle = (functions.resize && !flags.transient); + decorations.maximize = functions.maximize; break; }