X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2FWindow.cc;h=c260818c68ba271e97dce45fe7c89ffca0bede36;hb=f763814b338f9418e705309ddc87f68140d7888a;hp=b129121c50b59e03f75bd7343222c64bf41007dd;hpb=d7a655137bdb7f02cb79714e7d92aa0c26a55520;p=chaz%2Fopenbox diff --git a/src/Window.cc b/src/Window.cc index b129121c..c260818c 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -179,7 +179,7 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { blackbox->saveWindowSearch(frame.window, this); - frame.plate = createChildWindow(frame.window); + frame.plate = createChildWindow(frame.window, ExposureMask); blackbox->saveWindowSearch(frame.plate, this); // determine if this is a transient window @@ -212,7 +212,8 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { break; case Type_Normal: - // normal windows retain all of the possible decorations and functionality + // normal windows retain all of the possible decorations and + // functionality break; } } else { @@ -473,9 +474,7 @@ Window BlackboxWindow::createToplevelWindow(void) { attrib_create.background_pixmap = None; attrib_create.colormap = screen->getColormap(); attrib_create.override_redirect = True; - attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask | - ButtonMotionMask | - EnterWindowMask | LeaveWindowMask; + attrib_create.event_mask = EnterWindowMask | LeaveWindowMask; return XCreateWindow(blackbox->getXDisplay(), screen->getRootWindow(), 0, 0, 1, 1, frame.border_w, screen->getDepth(), @@ -488,14 +487,15 @@ Window BlackboxWindow::createToplevelWindow(void) { * Creates a child window, and optionally associates a given cursor with * the new window. */ -Window BlackboxWindow::createChildWindow(Window parent, Cursor cursor) { +Window BlackboxWindow::createChildWindow(Window parent, + unsigned long event_mask, + Cursor cursor) { XSetWindowAttributes attrib_create; unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWEventMask; attrib_create.background_pixmap = None; - attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask | - ButtonMotionMask | ExposureMask; + attrib_create.event_mask = event_mask; if (cursor) { create_mask |= CWCursor; @@ -590,8 +590,8 @@ void BlackboxWindow::decorate(void) { } if (decorations & Decor_Border) { - frame.fborder_pixel = screen->getWindowStyle()->f_focus.pixel(); - frame.uborder_pixel = screen->getWindowStyle()->f_unfocus.pixel(); + frame.fborder_pixel = screen->getWindowStyle()->f_focus.color().pixel(); + frame.uborder_pixel = screen->getWindowStyle()->f_unfocus.color().pixel(); } if (decorations & Decor_Handle) { @@ -646,15 +646,23 @@ void BlackboxWindow::decorateLabel(void) { void BlackboxWindow::createHandle(void) { - frame.handle = createChildWindow(frame.window); + frame.handle = createChildWindow(frame.window, + ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | ExposureMask); blackbox->saveWindowSearch(frame.handle, this); frame.left_grip = - createChildWindow(frame.handle, blackbox->getLowerLeftAngleCursor()); + createChildWindow(frame.handle, + ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | ExposureMask, + blackbox->getLowerLeftAngleCursor()); blackbox->saveWindowSearch(frame.left_grip, this); frame.right_grip = - createChildWindow(frame.handle, blackbox->getLowerRightAngleCursor()); + createChildWindow(frame.handle, + ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | ExposureMask, + blackbox->getLowerRightAngleCursor()); blackbox->saveWindowSearch(frame.right_grip, this); } @@ -686,8 +694,12 @@ void BlackboxWindow::destroyHandle(void) { void BlackboxWindow::createTitlebar(void) { - frame.title = createChildWindow(frame.window); - frame.label = createChildWindow(frame.title); + frame.title = createChildWindow(frame.window, + ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | ExposureMask); + frame.label = createChildWindow(frame.title, + ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | ExposureMask); blackbox->saveWindowSearch(frame.title, this); blackbox->saveWindowSearch(frame.label, this); @@ -739,7 +751,10 @@ void BlackboxWindow::destroyTitlebar(void) { void BlackboxWindow::createCloseButton(void) { if (frame.title != None) { - frame.close_button = createChildWindow(frame.title); + frame.close_button = createChildWindow(frame.title, + ButtonPressMask | + ButtonReleaseMask | + ButtonMotionMask | ExposureMask); blackbox->saveWindowSearch(frame.close_button, this); } } @@ -754,7 +769,10 @@ void BlackboxWindow::destroyCloseButton(void) { void BlackboxWindow::createIconifyButton(void) { if (frame.title != None) { - frame.iconify_button = createChildWindow(frame.title); + frame.iconify_button = createChildWindow(frame.title, + ButtonPressMask | + ButtonReleaseMask | + ButtonMotionMask | ExposureMask); blackbox->saveWindowSearch(frame.iconify_button, this); } } @@ -769,7 +787,10 @@ void BlackboxWindow::destroyIconifyButton(void) { void BlackboxWindow::createMaximizeButton(void) { if (frame.title != None) { - frame.maximize_button = createChildWindow(frame.title); + frame.maximize_button = createChildWindow(frame.title, + ButtonPressMask | + ButtonReleaseMask | + ButtonMotionMask | ExposureMask); blackbox->saveWindowSearch(frame.maximize_button, this); } } @@ -908,8 +929,7 @@ void BlackboxWindow::grabButtons(void) { // alt+middle lowers the window blackbox->grabButton(Button2, mod_mask, frame.window, True, ButtonReleaseMask, GrabModeAsync, GrabModeAsync, - frame.window, None, - screen->allowScrollLock()); + frame.window, None, screen->allowScrollLock()); } @@ -1069,6 +1089,15 @@ void BlackboxWindow::getWMName(void) { client.title = i18n(WindowSet, WindowUnnamed, "Unnamed"); xatom->setValue(client.window, XAtom::net_wm_visible_name, XAtom::utf8, client.title); + +#define DEBUG_WITH_ID 1 +#ifdef DEBUG_WITH_ID + // the 16 is the 8 chars of the debug text plus the number + char *tmp = new char[client.title.length() + 16]; + sprintf(tmp, "%s; id: 0x%lx", client.title.c_str(), client.window); + client.title = tmp; + delete tmp; +#endif } @@ -1189,14 +1218,11 @@ void BlackboxWindow::getWMNormalHints(void) { client.max_aspect_x = client.max_aspect_y = 1; #endif - /* - use the full screen, not the strut modified size. otherwise when the - availableArea changes max_width/height will be incorrect and lead to odd - rendering bugs. - */ - const Rect& screen_area = screen->getRect(); - client.max_width = screen_area.width(); - client.max_height = screen_area.height(); + // don't limit the size of a window, the default max width is the biggest + // possible + client.max_width = (unsigned) -1; + client.max_height = (unsigned) -1; + if (! XGetWMNormalHints(blackbox->getXDisplay(), client.window, &sizehint, &icccm_mask)) @@ -1668,7 +1694,7 @@ bool BlackboxWindow::setInputFocus(void) { void BlackboxWindow::iconify(void) { - if (flags.iconic) return; + if (flags.iconic || ! (functions & Func_Iconify)) return; // We don't need to worry about resizing because resizing always grabs the X // server. This should only ever happen if using opaque moving. @@ -1772,6 +1798,8 @@ void BlackboxWindow::deiconify(bool reassoc, bool raise) { void BlackboxWindow::close(void) { + if (! (functions & Func_Close)) return; + XEvent ce; ce.xclient.type = ClientMessage; ce.xclient.message_type = xatom->getAtom(XAtom::wm_protocols); @@ -1817,6 +1845,8 @@ void BlackboxWindow::withdraw(void) { void BlackboxWindow::maximize(unsigned int button) { + if (! (functions & Func_Maximize)) return; + // We don't need to worry about resizing because resizing always grabs the X // server. This should only ever happen if using opaque moving. if (flags.moving) @@ -2710,7 +2740,7 @@ void BlackboxWindow::reparentNotifyEvent(const XReparentEvent *re) { void BlackboxWindow::propertyNotifyEvent(const XPropertyEvent *pe) { - if (pe->state == PropertyDelete) + if (pe->state == PropertyDelete || ! validateClient()) return; #if 0 @@ -2838,7 +2868,7 @@ void BlackboxWindow::configureRequestEvent(const XConfigureRequestEvent *cr) { client.old_bw = cr->border_width; if (cr->value_mask & (CWX | CWY | CWWidth | CWHeight)) { - Rect req = frame.rect; + frame.changing = frame.rect; if (cr->value_mask & (CWX | CWY)) { if (cr->value_mask & CWX) @@ -2846,16 +2876,45 @@ void BlackboxWindow::configureRequestEvent(const XConfigureRequestEvent *cr) { if (cr->value_mask & CWY) client.rect.setY(cr->y); - applyGravity(req); + applyGravity(frame.changing); } - if (cr->value_mask & CWWidth) - req.setWidth(cr->width + frame.margin.left + frame.margin.right); + if (cr->value_mask & (CWWidth | CWHeight)) { + if (cr->value_mask & CWWidth) + frame.changing.setWidth(cr->width + + frame.margin.left + frame.margin.right); - if (cr->value_mask & CWHeight) - req.setHeight(cr->height + frame.margin.top + frame.margin.bottom); + if (cr->value_mask & CWHeight) + frame.changing.setHeight(cr->height + + frame.margin.top + frame.margin.bottom); - configure(req.x(), req.y(), req.width(), req.height()); + /* + if a position change ha been specified, then that position will be used + instead of determining a position based on the window's gravity. + */ + if (cr->value_mask & (CWX | CWY)) { + Corner corner; + switch (client.win_gravity) { + case NorthEastGravity: + case EastGravity: + corner = TopRight; + break; + case SouthWestGravity: + case SouthGravity: + corner = BottomLeft; + break; + case SouthEastGravity: + corner = BottomRight; + break; + default: // NorthWest, Static, etc + corner = TopLeft; + } + constrain(corner); + } + } + + configure(frame.changing.x(), frame.changing.y(), + frame.changing.width(), frame.changing.height()); } if (cr->value_mask & CWStackMode && !isDesktop()) { @@ -3017,6 +3076,8 @@ void BlackboxWindow::buttonReleaseEvent(const XButtonEvent *re) { void BlackboxWindow::beginMove(int x_root, int y_root) { + if (! (functions & Func_Move)) return; + assert(! (flags.resizing || flags.moving)); /* @@ -3135,6 +3196,9 @@ void BlackboxWindow::doWorkspaceWarping(int x_root, int y_root, int &dx) { screen->reassociateWindow(this, dest, False); screen->changeWorkspaceID(dest); + if (screen->doOpaqueMove()) + XGrabServer(blackbox->getXDisplay()); + XUngrabPointer(blackbox->getXDisplay(), CurrentTime); XWarpPointer(blackbox->getXDisplay(), None, screen->getRootWindow(), 0, 0, 0, 0, @@ -3144,6 +3208,9 @@ void BlackboxWindow::doWorkspaceWarping(int x_root, int y_root, int &dx) { GrabModeAsync, GrabModeAsync, None, blackbox->getMoveCursor(), CurrentTime); + if (screen->doOpaqueMove()) + XUngrabServer(blackbox->getXDisplay()); + if (focus) setInputFocus(); @@ -3472,11 +3539,14 @@ void BlackboxWindow::endMove(void) { void BlackboxWindow::beginResize(int x_root, int y_root, Corner dir) { + if (! (functions & Func_Resize)) return; + assert(! (flags.resizing || flags.moving)); /* - Only one window can be moved/resized at a time. If another window is already - being moved or resized, then stop it before whating to work with this one. + Only one window can be moved/resized at a time. If another window is + already being moved or resized, then stop it before whating to work with + this one. */ BlackboxWindow *changing = blackbox->getChangingWindow(); if (changing && changing != this) { @@ -3551,34 +3621,42 @@ void BlackboxWindow::doResize(int x_root, int y_root) { unsigned int gw, gh; Corner anchor; + int dx, dy; // the amount of change in the size of the window switch (resize_dir) { case BottomLeft: anchor = TopRight; - frame.changing.setSize(frame.rect.width() - (x_root - frame.grab_x), - frame.rect.height() + (y_root - frame.grab_y)); + dx = - (x_root - frame.grab_x); + dy = + (y_root - frame.grab_y); break; case BottomRight: anchor = TopLeft; - frame.changing.setSize(frame.rect.width() + (x_root - frame.grab_x), - frame.rect.height() + (y_root - frame.grab_y)); + dx = + (x_root - frame.grab_x); + dy = + (y_root - frame.grab_y); break; case TopLeft: anchor = BottomRight; - frame.changing.setSize(frame.rect.width() - (x_root - frame.grab_x), - frame.rect.height() - (y_root - frame.grab_y)); + dx = - (x_root - frame.grab_x); + dy = - (y_root - frame.grab_y); break; case TopRight: anchor = BottomLeft; - frame.changing.setSize(frame.rect.width() + (x_root - frame.grab_x), - frame.rect.height() - (y_root - frame.grab_y)); + dx = + (x_root - frame.grab_x); + dy = - (y_root - frame.grab_y); break; default: assert(false); // unhandled Corner return; // unreachable, for the compiler } - + + // make sure the user cant resize the window smaller than 0, which makes it + // wrap around and become huge + if (dx < -(signed)client.rect.width()) dx = -(signed)client.rect.width(); + if (dy < -(signed)client.rect.height()) dy = -(signed)client.rect.height(); + + frame.changing.setSize(frame.rect.width() + dx, frame.rect.height() + dy); + constrain(anchor, &gw, &gh); XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(), @@ -3682,14 +3760,16 @@ void BlackboxWindow::enterNotifyEvent(const XCrossingEvent* ce) { } } - if ((! leave || inferior) && ! isFocused()) { - bool success = setInputFocus(); - if (success) // if focus succeeded install the colormap - installColormap(True); // XXX: shouldnt we honour no install? - } + if (! leave || inferior) { + if (! isFocused()) { + bool success = setInputFocus(); + if (success) // if focus succeeded install the colormap + installColormap(True); // XXX: shouldnt we honour no install? + } - if (screen->doAutoRaise()) - timer->start(); + if (screen->doAutoRaise()) + timer->start(); + } }