X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2FWindow.cc;h=7cf8ec1bdf892126e3eaefff9cfbee163a263000;hb=63f8386dde9fb610492dd9a10d0a688f16d0dcf4;hp=56ee90a33b9d0f15310fcea391a57a7d9baf3d6c;hpb=ba6e2034e7a0bea0e2a71d3e90a808f02bdb5629;p=chaz%2Fopenbox diff --git a/src/Window.cc b/src/Window.cc index 56ee90a3..7cf8ec1b 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -1,6 +1,7 @@ // Window.cc for Openbox -// Copyright (c) 2001 Sean 'Shaleh' Perry -// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net) +// Copyright (c) 2002 - 2002 Ben Jansens (ben at orodu.net) +// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry (shaleh at debian.org) +// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net) // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -33,9 +34,9 @@ #include #include -#ifdef STDC_HEADERS +#ifdef HAVE_STRING_H # include -#endif // STDC_HEADERS +#endif // HAVE_STRING_H #ifdef DEBUG # ifdef HAVE_STDIO_H @@ -54,6 +55,7 @@ #ifdef SLIT # include "Slit.h" #endif // SLIT +#include "Util.h" /* * Initializes the class with default values/the window's set initial values. @@ -168,9 +170,8 @@ OpenboxWindow::OpenboxWindow(Openbox &o, Window w, BScreen *s) : openbox(o) { #ifdef SLIT if (client.initial_state == WithdrawnState) { screen->getSlit()->addClient(client.window); - delete this; - openbox.ungrab(); + delete this; return; } #endif // SLIT @@ -216,7 +217,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(); @@ -224,9 +225,9 @@ OpenboxWindow::OpenboxWindow(Openbox &o, Window w, BScreen *s) : openbox(o) { if ((openbox.isStartup()) || (frame.x >= 0 && (signed) (frame.y + frame.y_border) >= 0 && - frame.x <= (signed) screen->getWidth() && - frame.y <= (signed) screen->getHeight())) - place_window = False; + frame.x <= (signed) screen->size().w() && + frame.y <= (signed) screen->size().h())) + place_window = false; } frame.window = createToplevelWindow(frame.x, frame.y, frame.width, @@ -259,18 +260,18 @@ OpenboxWindow::OpenboxWindow(Openbox &o, Window w, BScreen *s) : openbox(o) { associateClientWindow(); - if (! screen->isSloppyFocus()) + if (! screen->sloppyFocus()) openbox.grabButton(Button1, 0, frame.plate, True, ButtonPressMask, - GrabModeSync, GrabModeSync, None, None); + GrabModeSync, GrabModeSync, frame.plate, None); openbox.grabButton(Button1, Mod1Mask, frame.window, True, ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, - GrabModeAsync, None, openbox.getMoveCursor()); + GrabModeAsync, frame.window, openbox.getMoveCursor()); openbox.grabButton(Button2, Mod1Mask, frame.window, True, - ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None); + ButtonReleaseMask, GrabModeAsync, GrabModeAsync, frame.window, None); openbox.grabButton(Button3, Mod1Mask, frame.window, True, ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, - GrabModeAsync, None, None); + GrabModeAsync, frame.window, None); positionWindows(); XRaiseWindow(display, frame.plate); @@ -538,24 +539,6 @@ void OpenboxWindow::associateClientWindow(void) { if (decorations.iconify) createIconifyButton(); if (decorations.maximize) createMaximizeButton(); if (decorations.close) createCloseButton(); - - if (frame.ubutton) { - if (frame.close_button) - XSetWindowBackgroundPixmap(display, frame.close_button, frame.ubutton); - if (frame.maximize_button) - XSetWindowBackgroundPixmap(display, frame.maximize_button, - frame.ubutton); - if (frame.iconify_button) - XSetWindowBackgroundPixmap(display, frame.iconify_button, frame.ubutton); - } else { - if (frame.close_button) - XSetWindowBackground(display, frame.close_button, frame.ubutton_pixel); - if (frame.maximize_button) - XSetWindowBackground(display, frame.maximize_button, - frame.ubutton_pixel); - if (frame.iconify_button) - XSetWindowBackground(display, frame.iconify_button, frame.ubutton_pixel); - } } @@ -739,7 +722,7 @@ void OpenboxWindow::createMaximizeButton(void) { } -void OpenboxWindow::positionButtons(Bool redecorate_label) { +void OpenboxWindow::positionButtons() { const char *format = openbox.getTitleBarLayout(); const unsigned int bw = frame.bevel_w + 1; const unsigned int by = frame.bevel_w + 1; @@ -760,37 +743,40 @@ void OpenboxWindow::positionButtons(Bool redecorate_label) { for (int i = 0; format[i] != '\0' && i < 4; i++) { switch(format[i]) { case 'C': - if (decorations.close && frame.close_button != None) { + if (decorations.close) { + if (frame.close_button == None) + createCloseButton(); XMoveResizeWindow(display, frame.close_button, bx, by, frame.button_w, frame.button_h); XMapWindow(display, frame.close_button); XClearWindow(display, frame.close_button); bx += frame.button_w + bw; hasclose = true; - } else if (frame.close_button) - XUnmapWindow(display, frame.close_button); + } break; case 'I': - if (decorations.iconify && frame.iconify_button != None) { + if (decorations.iconify) { + if (frame.iconify_button == None) + createIconifyButton(); XMoveResizeWindow(display, frame.iconify_button, bx, by, frame.button_w, frame.button_h); XMapWindow(display, frame.iconify_button); XClearWindow(display, frame.iconify_button); bx += frame.button_w + bw; hasiconify = true; - } else if (frame.close_button) - XUnmapWindow(display, frame.close_button); + } break; case 'M': - if (decorations.maximize && frame.maximize_button != None) { + if (decorations.maximize) { + if (frame.maximize_button == None) + createMaximizeButton(); XMoveResizeWindow(display, frame.maximize_button, bx, by, frame.button_w, frame.button_h); XMapWindow(display, frame.maximize_button); XClearWindow(display, frame.maximize_button); bx += frame.button_w + bw; hasmaximize = true; - } else if (frame.close_button) - XUnmapWindow(display, frame.close_button); + } break; case 'L': XMoveResizeWindow(display, frame.label, bx, by - 1, @@ -800,20 +786,22 @@ void OpenboxWindow::positionButtons(Bool redecorate_label) { } } - if (!hasclose) { - openbox.removeWindowSearch(frame.close_button); - XDestroyWindow(display, frame.close_button); + if (!hasclose && frame.close_button) { + openbox.removeWindowSearch(frame.close_button); + XDestroyWindow(display, frame.close_button); + frame.close_button = None; } - if (!hasiconify) { - openbox.removeWindowSearch(frame.iconify_button); - XDestroyWindow(display, frame.iconify_button); + if (!hasiconify && frame.iconify_button) { + openbox.removeWindowSearch(frame.iconify_button); + XDestroyWindow(display, frame.iconify_button); + frame.iconify_button = None; } - if (!hasmaximize) { - openbox.removeWindowSearch(frame.maximize_button); - XDestroyWindow(display, frame.maximize_button); + if (!hasmaximize && frame.iconify_button) { + openbox.removeWindowSearch(frame.maximize_button); + XDestroyWindow(display, frame.maximize_button); + frame.maximize_button = None; } - if (redecorate_label) - decorateLabel(); + redrawLabel(); redrawAllButtons(); } @@ -847,7 +835,7 @@ void OpenboxWindow::reconfigure(void) { configure(frame.x, frame.y, frame.width, frame.height); - if (! screen->isSloppyFocus()) + if (! screen->sloppyFocus()) openbox.grabButton(Button1, 0, frame.plate, True, ButtonPressMask, GrabModeSync, GrabModeSync, None, None); else @@ -1071,8 +1059,8 @@ void OpenboxWindow::getWMNormalHints(void) { client.min_width = client.min_height = client.base_width = client.base_height = client.width_inc = client.height_inc = 1; - client.max_width = screen->getWidth(); - client.max_height = screen->getHeight(); + client.max_width = screen->size().w(); + client.max_height = screen->size().h(); client.min_aspect_x = client.min_aspect_y = client.max_aspect_x = client.max_aspect_y = 1; client.win_gravity = NorthWestGravity; @@ -1314,10 +1302,9 @@ void OpenboxWindow::configure(int dx, int dy, XMoveWindow(display, frame.window, frame.x, frame.y); + setFocusFlag(flags.focused); positionWindows(); decorate(); - setFocusFlag(flags.focused); - redrawAllButtons(); } else { frame.x = dx; frame.y = dy; @@ -1353,64 +1340,61 @@ void OpenboxWindow::configure(int dx, int dy, } -Bool OpenboxWindow::setInputFocus(void) { +bool OpenboxWindow::setInputFocus(void) { if (((signed) (frame.x + frame.width)) < 0) { if (((signed) (frame.y + frame.y_border)) < 0) configure(frame.border_w, frame.border_w, frame.width, frame.height); - else if (frame.y > (signed) screen->getHeight()) - configure(frame.border_w, screen->getHeight() - frame.height, + else if (frame.y > (signed) screen->size().h()) + configure(frame.border_w, screen->size().h() - frame.height, frame.width, frame.height); else configure(frame.border_w, frame.y + frame.border_w, frame.width, frame.height); - } else if (frame.x > (signed) screen->getWidth()) { + } else if (frame.x > (signed) screen->size().w()) { if (((signed) (frame.y + frame.y_border)) < 0) - configure(screen->getWidth() - frame.width, frame.border_w, + configure(screen->size().w() - frame.width, frame.border_w, frame.width, frame.height); - else if (frame.y > (signed) screen->getHeight()) - configure(screen->getWidth() - frame.width, - screen->getHeight() - frame.height, frame.width, frame.height); + else if (frame.y > (signed) screen->size().h()) + configure(screen->size().w() - frame.width, + screen->size().h() - frame.height, frame.width, frame.height); else - configure(screen->getWidth() - frame.width, + configure(screen->size().w() - frame.width, frame.y + frame.border_w, frame.width, frame.height); } openbox.grab(); if (! validateClient()) return False; - Bool ret = False; + bool ret = false; if (client.transient && flags.modal) { ret = client.transient->setInputFocus(); } else if (! flags.focused) { - if (focus_mode == F_LocallyActive || focus_mode == F_Passive) + if (focus_mode == F_LocallyActive || focus_mode == F_Passive) { XSetInputFocus(display, client.window, - RevertToPointerRoot, CurrentTime); - else - XSetInputFocus(display, screen->getRootWindow(), - RevertToNone, CurrentTime); - - openbox.setFocusedWindow(this); - - if (flags.send_focus_message) { - XEvent ce; - ce.xclient.type = ClientMessage; - ce.xclient.message_type = openbox.getWMProtocolsAtom(); - ce.xclient.display = display; - ce.xclient.window = client.window; - ce.xclient.format = 32; - ce.xclient.data.l[0] = openbox.getWMTakeFocusAtom(); - ce.xclient.data.l[1] = openbox.getLastTime(); - ce.xclient.data.l[2] = 0l; - ce.xclient.data.l[3] = 0l; - ce.xclient.data.l[4] = 0l; - XSendEvent(display, client.window, False, NoEventMask, &ce); - } + RevertToPointerRoot, CurrentTime); + openbox.focusWindow(this); + + if (flags.send_focus_message) { + XEvent ce; + ce.xclient.type = ClientMessage; + ce.xclient.message_type = openbox.getWMProtocolsAtom(); + ce.xclient.display = display; + ce.xclient.window = client.window; + ce.xclient.format = 32; + ce.xclient.data.l[0] = openbox.getWMTakeFocusAtom(); + ce.xclient.data.l[1] = openbox.getLastTime(); + ce.xclient.data.l[2] = 0l; + ce.xclient.data.l[3] = 0l; + ce.xclient.data.l[4] = 0l; + XSendEvent(display, client.window, False, NoEventMask, &ce); + } - if (screen->isSloppyFocus() && screen->doAutoRaise()) - timer->start(); + if (screen->sloppyFocus() && screen->autoRaise()) + timer->start(); - ret = True; + ret = true; + } } openbox.ungrab(); @@ -1422,6 +1406,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 +1436,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,7 +1452,19 @@ void OpenboxWindow::deiconify(Bool reassoc, Bool raise) { XMapSubwindows(display, frame.window); XMapWindow(display, frame.window); - if (flags.iconic && screen->doFocusNew()) setInputFocus(); + // 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; flags.iconic = False; @@ -1494,6 +1493,9 @@ void OpenboxWindow::close(void) { void OpenboxWindow::withdraw(void) { + if (flags.moving) + endMove(); + flags.visible = False; flags.iconic = False; @@ -1509,6 +1511,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(); @@ -1528,34 +1533,29 @@ void OpenboxWindow::maximize(unsigned int button) { openbox_attrib.premax_x = openbox_attrib.premax_y = 0; openbox_attrib.premax_w = openbox_attrib.premax_h = 0; - redrawAllButtons(); + redrawMaximizeButton(flags.maximized); setState(current_state); return; } - int dx = 0, dy = 0; - unsigned int dw, dh; - openbox_attrib.premax_x = frame.x; openbox_attrib.premax_y = frame.y; openbox_attrib.premax_w = frame.width; openbox_attrib.premax_h = frame.height; - dw = screen->getWidth(); + Rect space = screen->availableArea(); + unsigned int dw = space.w(), + dh = space.h(); dw -= frame.border_w * 2; dw -= frame.mwm_border_w * 2; dw -= client.base_width; - dh = screen->getHeight(); dh -= frame.border_w * 2; dh -= frame.mwm_border_w * 2; dh -= ((frame.handle_h + frame.border_w) * decorations.handle); dh -= client.base_height; dh -= frame.y_border; - if (! screen->doFullMax()) - dh -= screen->getToolbar()->getExposedHeight() + frame.border_w; - 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; @@ -1571,23 +1571,8 @@ void OpenboxWindow::maximize(unsigned int button) { dh += ((frame.handle_h + frame.border_w) * decorations.handle); dh += frame.mwm_border_w * 2; - dx += ((screen->getWidth() - dw) / 2) - frame.border_w; - - if (screen->doFullMax()) { - dy += ((screen->getHeight() - dh) / 2) - frame.border_w; - } else { - dy += (((screen->getHeight() - screen->getToolbar()->getExposedHeight()) - - dh) / 2) - frame.border_w; - - switch (screen->getToolbarPlacement()) { - case Toolbar::TopLeft: - case Toolbar::TopCenter: - case Toolbar::TopRight: - dy += screen->getToolbar()->getExposedHeight() + - frame.border_w; - break; - } - } + int dx = space.x() + ((space.w() - dw) / 2) - frame.border_w, + dy = space.y() + ((space.h() - dh) / 2) - frame.border_w; switch(button) { case 1: @@ -1622,12 +1607,13 @@ void OpenboxWindow::maximize(unsigned int button) { configure(dx, dy, dw, dh); screen->getWorkspace(workspace_number)->raiseWindow(this); - redrawAllButtons(); + redrawMaximizeButton(flags.maximized); setState(current_state); } void OpenboxWindow::setWorkspace(int n) { + ASSERT(n < screen->getWorkspaceCount()); workspace_number = n; openbox_attrib.flags |= AttribWorkspace; @@ -1740,8 +1726,9 @@ void OpenboxWindow::setFocusFlag(Bool focus) { XSetWindowBorder(display, frame.plate, frame.uborder_pixel); } - if (screen->isSloppyFocus() && screen->doAutoRaise() && timer->isTiming()) + if (screen->sloppyFocus() && screen->autoRaise() && timer->isTiming()) timer->stop(); + } @@ -2237,7 +2224,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; } @@ -2252,13 +2240,9 @@ void OpenboxWindow::mapNotifyEvent(XMapEvent *ne) { openbox.grab(); if (! validateClient()) return; - if (decorations.titlebar) positionButtons(); - setState(NormalState); - redrawAllButtons(); - - if (flags.transient || screen->doFocusNew()) + if (flags.transient || screen->focusNew()) setInputFocus(); else setFocusFlag(False); @@ -2282,6 +2266,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); @@ -2317,6 +2304,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; @@ -2416,7 +2405,10 @@ void OpenboxWindow::propertyNotifyEvent(Atom atom) { if (decorations.close && (! frame.close_button)) { createCloseButton(); - if (decorations.titlebar) positionButtons(True); + if (decorations.titlebar) { + positionButtons(); + decorateLabel(); + } if (windowmenu) windowmenu->reconfigure(); } } @@ -2503,8 +2495,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) { @@ -2593,7 +2583,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) { @@ -2641,7 +2631,7 @@ void OpenboxWindow::buttonPressEvent(XButtonEvent *be) { shade(); } - if (! (flags.focused || screen->isSloppyFocus()) ) { + if (! (flags.focused || screen->sloppyFocus()) ) { setInputFocus(); // any click focus' the window in 'click to focus' } if (stack_change < 0) { @@ -2719,21 +2709,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->doOpaqueMove()) { - 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) { @@ -2765,105 +2741,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->doOpaqueMove()) { - 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->getEdgeSnapThreshold(); - // width/height of the snapping window - unsigned int snap_w = frame.width + (frame.border_w * 2); - unsigned int snap_h = getHeight() + (frame.border_w * 2); - if (snap_distance) { - int drx = screen->getWidth() - (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->getWidth() - snap_w; - - int dtty, dbby, dty, dby; - switch (screen->getToolbarPlacement()) { - case Toolbar::TopLeft: - case Toolbar::TopCenter: - case Toolbar::TopRight: - dtty = screen->getToolbar()->getExposedHeight() + - frame.border_w; - dbby = screen->getHeight(); - break; - - default: - dtty = 0; - dbby = screen->getToolbar()->getY(); - 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->doOpaqueMove()) { - 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; - screen->showPosition(dx, dy); + 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; } - } 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; @@ -2979,7 +2999,7 @@ void OpenboxWindow::shapeEvent(XShapeEvent *) { #endif // SHAPE -Bool OpenboxWindow::validateClient(void) { +bool OpenboxWindow::validateClient(void) { XSync(display, False); XEvent e; @@ -2988,10 +3008,10 @@ Bool OpenboxWindow::validateClient(void) { XPutBackEvent(display, &e); openbox.ungrab(); - return False; + return false; } - return True; + return true; } @@ -3010,6 +3030,8 @@ void OpenboxWindow::restore(void) { XMapWindow(display, client.window); XFlush(display); + + delete this; } @@ -3067,21 +3089,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; } @@ -3177,9 +3203,9 @@ void OpenboxWindow::downsize(void) { void OpenboxWindow::right_fixsize(int *gx, int *gy) { // calculate the size of the client window and conform it to the // size specified by the size hints of the client window... - int dx = frame.resize_w - client.base_width - (frame.mwm_border_w * 2) - + int dx = 1 + frame.resize_w - client.base_width - (frame.mwm_border_w * 2) - (frame.border_w * 2) + (client.width_inc / 2); - int dy = frame.resize_h - frame.y_border - client.base_height - + int dy = 1 + frame.resize_h - frame.y_border - client.base_height - frame.handle_h - (frame.border_w * 3) - (frame.mwm_border_w * 2) + (client.height_inc / 2); @@ -3197,9 +3223,9 @@ void OpenboxWindow::right_fixsize(int *gx, int *gy) { dx = (dx * client.width_inc) + client.base_width; dy = (dy * client.height_inc) + client.base_height; - frame.resize_w = dx + (frame.mwm_border_w * 2) + (frame.border_w * 2); + frame.resize_w = dx + (frame.mwm_border_w * 2) + (frame.border_w * 2) - 1; frame.resize_h = dy + frame.y_border + frame.handle_h + - (frame.mwm_border_w * 2) + (frame.border_w * 3); + (frame.mwm_border_w * 2) + (frame.border_w * 3) - 1; if (resize_zone & ZoneTop) frame.resize_y = frame.y + frame.height - frame.resize_h + screen->getBorderWidth() * 2; @@ -3209,9 +3235,9 @@ void OpenboxWindow::right_fixsize(int *gx, int *gy) { void OpenboxWindow::left_fixsize(int *gx, int *gy) { // calculate the size of the client window and conform it to the // size specified by the size hints of the client window... - int dx = frame.x + frame.width - frame.resize_x - client.base_width - + int dx = 1 + frame.x + frame.width - frame.resize_x - client.base_width - (frame.mwm_border_w * 2) + (client.width_inc / 2); - int dy = frame.resize_h - frame.y_border - client.base_height - + int dy = 1 + frame.resize_h - frame.y_border - client.base_height - frame.handle_h - (frame.border_w * 3) - (frame.mwm_border_w * 2) + (client.height_inc / 2); @@ -3229,11 +3255,11 @@ void OpenboxWindow::left_fixsize(int *gx, int *gy) { dx = (dx * client.width_inc) + client.base_width; dy = (dy * client.height_inc) + client.base_height; - frame.resize_w = dx + (frame.mwm_border_w * 2) + (frame.border_w * 2); + frame.resize_w = dx + (frame.mwm_border_w * 2) + (frame.border_w * 2) - 1; frame.resize_x = frame.x + frame.width - frame.resize_w + (frame.border_w * 2); frame.resize_h = dy + frame.y_border + frame.handle_h + - (frame.mwm_border_w * 2) + (frame.border_w * 3); + (frame.mwm_border_w * 2) + (frame.border_w * 3) - 1; if (resize_zone & ZoneTop) frame.resize_y = frame.y + frame.height - frame.resize_h + screen->getBorderWidth() * 2;