X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2FWindow.cc;h=680943e214d5eb3c3e8453b8043f4573ad086064;hb=87e63d53af67d5ea98f55a27007663d4c9c8fc6c;hp=32fe86c75c373205b0ea01d379cf1bc96749deb1;hpb=9667f3a0e9d9c70e313db9930f00743992613033;p=chaz%2Fopenbox diff --git a/src/Window.cc b/src/Window.cc index 32fe86c7..680943e2 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -40,7 +40,7 @@ extern "C" { #endif // DEBUG #ifdef HAVE_STDLIB_H - #include +# include #endif // HAVE_STDLIB_H } @@ -128,17 +128,17 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { frame.border_w = 1; frame.window = frame.plate = frame.title = frame.handle = None; - frame.close_button = frame.iconify_button = frame.maximize_button = None; + frame.close_button = frame.iconify_button = frame.maximize_button = + frame.stick_button = None; frame.right_grip = frame.left_grip = None; frame.ulabel_pixel = frame.flabel_pixel = frame.utitle_pixel = frame.ftitle_pixel = frame.uhandle_pixel = frame.fhandle_pixel = - frame.ubutton_pixel = frame.fbutton_pixel = frame.pbutton_pixel = - frame.uborder_pixel = frame.fborder_pixel = frame.ugrip_pixel = - frame.fgrip_pixel = 0; + frame.ubutton_pixel = frame.fbutton_pixel = frame.uborder_pixel = + frame.fborder_pixel = frame.ugrip_pixel = 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 = None; + frame.ugrip = frame.fgrip = None; functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize; mwm_decorations = Decor_Titlebar | Decor_Handle | Decor_Border | @@ -474,7 +474,13 @@ Window BlackboxWindow::createToplevelWindow(void) { attrib_create.background_pixmap = None; attrib_create.colormap = screen->getColormap(); attrib_create.override_redirect = True; - attrib_create.event_mask = EnterWindowMask | LeaveWindowMask; + attrib_create.event_mask = EnterWindowMask | LeaveWindowMask | + ButtonPress; + /* + We catch button presses because other wise they get passed down to the + root window, which will then cause root menus to show when you click the + window's frame. + */ return XCreateWindow(blackbox->getXDisplay(), screen->getRootWindow(), 0, 0, 1, 1, frame.border_w, screen->getDepth(), @@ -564,11 +570,50 @@ void BlackboxWindow::decorate(void) { if (! frame.ubutton) frame.ubutton_pixel = texture->color().pixel(); - texture = &(screen->getWindowStyle()->b_pressed); - frame.pbutton = texture->render(frame.button_w, frame.button_w, - frame.pbutton); - if (! frame.pbutton) - frame.pbutton_pixel = texture->color().pixel(); + unsigned char needsPressed = 0; + + texture = &(screen->getWindowStyle()->b_pressed_focus); + + if (texture->texture() != BTexture::NoTexture) { + frame.pfbutton = texture->render(frame.button_w, frame.button_w, + frame.pfbutton); + if (! frame.pfbutton) + frame.pfbutton_pixel = texture->color().pixel(); + } else { + needsPressed = 0x1; + } + + texture = &(screen->getWindowStyle()->b_pressed_unfocus); + + if (texture->texture() != BTexture::NoTexture) { + frame.pubutton = texture->render(frame.button_w, frame.button_w, + frame.pubutton); + if (! frame.pubutton) + frame.pubutton = texture->color().pixel(); + } else { + needsPressed |= 0x2; + } + + // if we either pressed unfocused, or pressed focused were undefined, + // make them inherit from the old resource. It's a hack for sure, but + // it allows for some backwards and forwards compatibility. + if (needsPressed) { + texture = &(screen->getWindowStyle()->b_pressed); + + if (needsPressed & 0x1) { + frame.pfbutton = texture->render(frame.button_w, frame.button_w, + frame.pfbutton); + if (! frame.pfbutton) + frame.pfbutton_pixel = texture->color().pixel(); + } + if (needsPressed & 0x2) { + frame.pubutton = texture->render(frame.button_w, frame.button_w, + frame.pubutton); + if (! frame.pubutton) + frame.pubutton = texture->color().pixel(); + } + + } if (decorations & Decor_Titlebar) { texture = &(screen->getWindowStyle()->t_focus); @@ -719,6 +764,9 @@ void BlackboxWindow::destroyTitlebar(void) { if (frame.maximize_button) destroyMaximizeButton(); + if (frame.stick_button) + destroyStickyButton(); + if (frame.ftitle) screen->getImageControl()->removeImage(frame.ftitle); @@ -737,9 +785,6 @@ void BlackboxWindow::destroyTitlebar(void) { if (frame.ubutton) screen->getImageControl()->removeImage(frame.ubutton); - if (frame.pbutton) - screen->getImageControl()->removeImage(frame.pbutton); - blackbox->removeWindowSearch(frame.title); blackbox->removeWindowSearch(frame.label); @@ -802,13 +847,28 @@ void BlackboxWindow::destroyMaximizeButton(void) { frame.maximize_button = None; } +void BlackboxWindow::createStickyButton(void) { + if (frame.title != None) { + frame.stick_button = createChildWindow(frame.title, + ButtonPressMask | + ButtonReleaseMask | + ButtonMotionMask | ExposureMask); + blackbox->saveWindowSearch(frame.stick_button, this); + } +} + +void BlackboxWindow::destroyStickyButton(void) { + blackbox->removeWindowSearch(frame.stick_button); + XDestroyWindow(blackbox->getXDisplay(), frame.stick_button); + frame.stick_button = None; +} void BlackboxWindow::positionButtons(bool redecorate_label) { string layout = blackbox->getTitlebarLayout(); string parsed; - bool hasclose, hasiconify, hasmaximize, haslabel; - hasclose = hasiconify = hasmaximize = haslabel = false; + bool hasclose, hasiconify, hasmaximize, haslabel, hasstick; + hasclose = hasiconify = hasmaximize = haslabel = hasstick = false; string::const_iterator it, end; for (it = layout.begin(), end = layout.end(); it != end; ++it) { @@ -825,6 +885,12 @@ void BlackboxWindow::positionButtons(bool redecorate_label) { parsed += *it; } break; + case 'S': + if (!hasstick) { + hasstick = true; + parsed += *it; + } + break; case 'M': if (! hasmaximize && (decorations & Decor_Maximize)) { hasmaximize = true; @@ -836,14 +902,18 @@ void BlackboxWindow::positionButtons(bool redecorate_label) { haslabel = true; parsed += *it; } + break; } } + if (! hasclose && frame.close_button) destroyCloseButton(); if (! hasiconify && frame.iconify_button) destroyIconifyButton(); if (! hasmaximize && frame.maximize_button) destroyMaximizeButton(); + if (! hasstick && frame.stick_button) + destroyStickyButton(); if (! haslabel) parsed += 'L'; // require that the label be in the layout @@ -869,6 +939,12 @@ void BlackboxWindow::positionButtons(bool redecorate_label) { frame.button_w, frame.button_w); x += frame.button_w + bsep; break; + case 'S': + if (! frame.stick_button) createStickyButton(); + XMoveResizeWindow(blackbox->getXDisplay(), frame.stick_button, x, by, + frame.button_w, frame.button_w); + x += frame.button_w + bsep; + break; case 'M': if (! frame.maximize_button) createMaximizeButton(); XMoveResizeWindow(blackbox->getXDisplay(), frame.maximize_button, x, by, @@ -1090,7 +1166,6 @@ void BlackboxWindow::getWMName(void) { 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]; @@ -2077,6 +2152,9 @@ void BlackboxWindow::stick(void) { setState(current_state); } + + redrawAllButtons(); + // go up the chain if (isTransient() && client.transient_for != (BlackboxWindow *) ~0ul && client.transient_for->isStuck() != flags.stuck) @@ -2542,114 +2620,189 @@ void BlackboxWindow::redrawAllButtons(void) const { if (frame.iconify_button) redrawIconifyButton(False); if (frame.maximize_button) redrawMaximizeButton(flags.maximized); if (frame.close_button) redrawCloseButton(False); + if (frame.stick_button) redrawStickyButton(flags.stuck); } -void BlackboxWindow::redrawIconifyButton(bool pressed) const { - if (! pressed) { +void BlackboxWindow::redrawButton(bool pressed, Window win, + Pixmap fppix, unsigned long fppixel, + Pixmap uppix, unsigned long uppixel, + Pixmap fpix, unsigned long fpixel, + Pixmap upix, unsigned long upixel) const { + Pixmap p; + unsigned long pix; + + if (pressed) { if (flags.focused) { - if (frame.fbutton) - XSetWindowBackgroundPixmap(blackbox->getXDisplay(), - frame.iconify_button, frame.fbutton); - else - XSetWindowBackground(blackbox->getXDisplay(), - frame.iconify_button, frame.fbutton_pixel); + p = fppix; + pix = fppixel; } else { - if (frame.ubutton) - XSetWindowBackgroundPixmap(blackbox->getXDisplay(), - frame.iconify_button, frame.ubutton); - else - XSetWindowBackground(blackbox->getXDisplay(), frame.iconify_button, - frame.ubutton_pixel); + p = uppix; + pix = uppixel; } } else { - if (frame.pbutton) - XSetWindowBackgroundPixmap(blackbox->getXDisplay(), - frame.iconify_button, frame.pbutton); - else - XSetWindowBackground(blackbox->getXDisplay(), - frame.iconify_button, frame.pbutton_pixel); + if (flags.focused) { + p = fpix; + pix = fpixel; + } else { + p = upix; + pix = upixel; + } } - XClearWindow(blackbox->getXDisplay(), frame.iconify_button); + + if (p) + XSetWindowBackgroundPixmap(blackbox->getXDisplay(), win, p); + else + XSetWindowBackground(blackbox->getXDisplay(), win, pix); - BPen pen((flags.focused) ? screen->getWindowStyle()->b_pic_focus : - screen->getWindowStyle()->b_pic_unfocus); - XDrawRectangle(blackbox->getXDisplay(), frame.iconify_button, pen.gc(), - 2, (frame.button_w - 5), (frame.button_w - 5), 2); } +void BlackboxWindow::redrawIconifyButton(bool pressed) const { + redrawButton(pressed, frame.iconify_button, + frame.pfbutton, frame.pfbutton_pixel, + frame.pubutton, frame.pubutton_pixel, + frame.fbutton, frame.fbutton_pixel, + frame.ubutton, frame.ubutton_pixel); -void BlackboxWindow::redrawMaximizeButton(bool pressed) const { - if (! pressed) { - if (flags.focused) { - if (frame.fbutton) - XSetWindowBackgroundPixmap(blackbox->getXDisplay(), - frame.maximize_button, frame.fbutton); - else - XSetWindowBackground(blackbox->getXDisplay(), frame.maximize_button, - frame.fbutton_pixel); - } else { - if (frame.ubutton) - XSetWindowBackgroundPixmap(blackbox->getXDisplay(), - frame.maximize_button, frame.ubutton); - else - XSetWindowBackground(blackbox->getXDisplay(), frame.maximize_button, - frame.ubutton_pixel); - } + XClearWindow(blackbox->getXDisplay(), frame.iconify_button); + BPen pen((flags.focused) ? screen->getWindowStyle()->b_pic_focus : + screen->getWindowStyle()->b_pic_unfocus); + +#ifdef BITMAPBUTTONS + PixmapMask pm = screen->getWindowStyle()->icon_button; + + if (screen->getWindowStyle()->icon_button.mask != None) { + XSetClipMask(blackbox->getXDisplay(), pen.gc(), pm.mask); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2); + + XFillRectangle(blackbox->getXDisplay(), frame.iconify_button, pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2, + (frame.button_w + pm.w)/2, (frame.button_w + pm.h)/2); + + XSetClipMask(blackbox->getXDisplay(), pen.gc(), None); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), 0, 0); } else { - if (frame.pbutton) - XSetWindowBackgroundPixmap(blackbox->getXDisplay(), - frame.maximize_button, frame.pbutton); - else - XSetWindowBackground(blackbox->getXDisplay(), frame.maximize_button, - frame.pbutton_pixel); +#endif // BITMAPBUTTONS + XDrawRectangle(blackbox->getXDisplay(), frame.iconify_button, pen.gc(), + 2, (frame.button_w - 5), (frame.button_w - 5), 2); +#ifdef BITMAPBUTTONS } +#endif // BITMAPBUTTONS +} + + +void BlackboxWindow::redrawMaximizeButton(bool pressed) const { + redrawButton(pressed, frame.maximize_button, + frame.pfbutton, frame.pfbutton_pixel, + frame.pubutton, frame.pubutton_pixel, + frame.fbutton, frame.fbutton_pixel, + frame.ubutton, frame.ubutton_pixel); + XClearWindow(blackbox->getXDisplay(), frame.maximize_button); BPen pen((flags.focused) ? screen->getWindowStyle()->b_pic_focus : screen->getWindowStyle()->b_pic_unfocus); - XDrawRectangle(blackbox->getXDisplay(), frame.maximize_button, pen.gc(), - 2, 2, (frame.button_w - 5), (frame.button_w - 5)); - XDrawLine(blackbox->getXDisplay(), frame.maximize_button, pen.gc(), - 2, 3, (frame.button_w - 3), 3); + +#ifdef BITMAPBUTTONS + PixmapMask pm = screen->getWindowStyle()->max_button; + + if (pm.mask != None) { + XSetClipMask(blackbox->getXDisplay(), pen.gc(), pm.mask); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2); + + XFillRectangle(blackbox->getXDisplay(), frame.maximize_button, pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2, + (frame.button_w + pm.w)/2, (frame.button_w + pm.h)/2); + + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), 0, 0 ); + XSetClipMask( blackbox->getXDisplay(), pen.gc(), None ); + } else { +#endif // BITMAPBUTTONS + XDrawRectangle(blackbox->getXDisplay(), frame.maximize_button, pen.gc(), + 2, 2, (frame.button_w - 5), (frame.button_w - 5)); + XDrawLine(blackbox->getXDisplay(), frame.maximize_button, pen.gc(), + 2, 3, (frame.button_w - 3), 3); +#ifdef BITMAPBUTTONS + } +#endif // BITMAPBUTTONS } void BlackboxWindow::redrawCloseButton(bool pressed) const { - if (! pressed) { - if (flags.focused) { - if (frame.fbutton) - XSetWindowBackgroundPixmap(blackbox->getXDisplay(), frame.close_button, - frame.fbutton); - else - XSetWindowBackground(blackbox->getXDisplay(), frame.close_button, - frame.fbutton_pixel); - } else { - if (frame.ubutton) - XSetWindowBackgroundPixmap(blackbox->getXDisplay(), frame.close_button, - frame.ubutton); - else - XSetWindowBackground(blackbox->getXDisplay(), frame.close_button, - frame.ubutton_pixel); - } - } else { - if (frame.pbutton) - XSetWindowBackgroundPixmap(blackbox->getXDisplay(), - frame.close_button, frame.pbutton); - else - XSetWindowBackground(blackbox->getXDisplay(), - frame.close_button, frame.pbutton_pixel); - } + redrawButton(pressed, frame.close_button, + frame.pfbutton, frame.pfbutton_pixel, + frame.pubutton, frame.pubutton_pixel, + frame.fbutton, frame.fbutton_pixel, + frame.ubutton, frame.ubutton_pixel); + XClearWindow(blackbox->getXDisplay(), frame.close_button); BPen pen((flags.focused) ? screen->getWindowStyle()->b_pic_focus : - screen->getWindowStyle()->b_pic_unfocus, 0, 2); - XDrawLine(blackbox->getXDisplay(), frame.close_button, pen.gc(), - 2, 2, (frame.button_w - 3), (frame.button_w - 3)); - XDrawLine(blackbox->getXDisplay(), frame.close_button, pen.gc(), - 2, (frame.button_w - 3), (frame.button_w - 3), 2); + screen->getWindowStyle()->b_pic_unfocus); + +#ifdef BITMAPBUTTONS + PixmapMask pm = screen->getWindowStyle()->close_button; + + if (pm.mask != None) { + XSetClipMask(blackbox->getXDisplay(), pen.gc(), pm.mask); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2); + + XFillRectangle(blackbox->getXDisplay(), frame.close_button, pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2, + (frame.button_w + pm.w)/2, (frame.button_w + pm.h)/2); + + + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), 0, 0 ); + XSetClipMask( blackbox->getXDisplay(), pen.gc(), None ); + } else { +#endif // BITMAPBUTTONS + XDrawLine(blackbox->getXDisplay(), frame.close_button, pen.gc(), + 2, 2, (frame.button_w - 3), (frame.button_w - 3)); + XDrawLine(blackbox->getXDisplay(), frame.close_button, pen.gc(), + 2, (frame.button_w - 3), (frame.button_w - 3), 2); +#ifdef BITMAPBUTTONS + } +#endif // BITMAPBUTTONS } +void BlackboxWindow::redrawStickyButton(bool pressed) const { + redrawButton(pressed, frame.stick_button, + frame.pfbutton, frame.pfbutton_pixel, + frame.pubutton, frame.pubutton_pixel, + frame.fbutton, frame.fbutton_pixel, + frame.ubutton, frame.ubutton_pixel); + + XClearWindow(blackbox->getXDisplay(), frame.stick_button); + + BPen pen((flags.focused) ? screen->getWindowStyle()->b_pic_focus : + screen->getWindowStyle()->b_pic_unfocus); + +#ifdef BITMAPBUTTONS + PixmapMask pm = screen->getWindowStyle()->stick_button; + + if (pm.mask != None) { + XSetClipMask(blackbox->getXDisplay(), pen.gc(), pm.mask); + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2); + + XFillRectangle(blackbox->getXDisplay(), frame.stick_button, pen.gc(), + (frame.button_w - pm.w)/2, (frame.button_w - pm.h)/2, + (frame.button_w + pm.w)/2, (frame.button_w + pm.h)/2); + + + XSetClipOrigin(blackbox->getXDisplay(), pen.gc(), 0, 0 ); + XSetClipMask( blackbox->getXDisplay(), pen.gc(), None ); + } else { +#endif // BITMAPBUTTONS + XFillRectangle(blackbox->getXDisplay(), frame.stick_button, pen.gc(), + frame.button_w/2 - 1, frame.button_w/2 -1, 2, 2 ); +#ifdef BITMAPBUTTONS + } +#endif +} void BlackboxWindow::mapRequestEvent(const XMapRequestEvent *re) { if (re->window != client.window) @@ -2664,7 +2817,8 @@ void BlackboxWindow::mapRequestEvent(const XMapRequestEvent *re) { Even though the window wants to be shown, if it is not on the current workspace, then it isn't going to be shown right now. */ - if (blackbox_attrib.workspace != screen->getCurrentWorkspaceID() && + if (! flags.stuck && + blackbox_attrib.workspace != screen->getCurrentWorkspaceID() && blackbox_attrib.workspace < screen->getWorkspaceCount()) if (current_state == NormalState) current_state = WithdrawnState; @@ -2865,6 +3019,8 @@ void BlackboxWindow::exposeEvent(const XExposeEvent *ee) { redrawMaximizeButton(flags.maximized); else if (frame.iconify_button == ee->window) redrawIconifyButton(False); + else if (frame.stick_button == ee->window) + redrawStickyButton(flags.stuck); } @@ -2897,10 +3053,10 @@ void BlackboxWindow::configureRequestEvent(const XConfigureRequestEvent *cr) { frame.margin.top + frame.margin.bottom); /* - 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 a position change has 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)) { + if (! (cr->value_mask & (CWX | CWY))) { Corner corner; switch (client.win_gravity) { case NorthEastGravity: @@ -2958,6 +3114,8 @@ void BlackboxWindow::buttonPressEvent(const XButtonEvent *be) { redrawIconifyButton(True); } else if (frame.close_button == be->window) { redrawCloseButton(True); + } else if (frame.stick_button == be->window) { + redrawStickyButton(True); } else if (frame.plate == be->window) { if (windowmenu && windowmenu->isVisible()) windowmenu->hide(); @@ -2981,7 +3139,8 @@ void BlackboxWindow::buttonPressEvent(const XButtonEvent *be) { screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this); } } else if (be->button == 2 && (be->window != frame.iconify_button) && - (be->window != frame.close_button)) { + (be->window != frame.close_button) && + (be->window != frame.stick_button)) { screen->getWorkspace(blackbox_attrib.workspace)->lowerWindow(this); } else if (windowmenu && be->button == 3 && (frame.title == be->window || frame.label == be->window || @@ -3010,12 +3169,16 @@ void BlackboxWindow::buttonPressEvent(const XButtonEvent *be) { if (mx < left_edge) mx = left_edge; - if (mx > right_edge) + else if (mx > right_edge) mx = right_edge; if (my < top_edge) my = top_edge; - if (my > bottom_edge) + else if (my > bottom_edge) my = bottom_edge; + + if (my + windowmenu->getHeight() > screen->getHeight()) + my = screen->getHeight() - windowmenu->getHeight() - + (screen->getBorderWidth() * 2); windowmenu->move(mx, my); windowmenu->show(); @@ -3029,7 +3192,8 @@ void BlackboxWindow::buttonPressEvent(const XButtonEvent *be) { be->window == frame.title || be->window == frame.maximize_button || be->window == frame.iconify_button || - be->window == frame.close_button) && + be->window == frame.close_button || + be->window == frame.stick_button) && ! flags.shaded) shade(); // mouse wheel down @@ -3038,7 +3202,8 @@ void BlackboxWindow::buttonPressEvent(const XButtonEvent *be) { be->window == frame.title || be->window == frame.maximize_button || be->window == frame.iconify_button || - be->window == frame.close_button) && + be->window == frame.close_button || + be->window == frame.stick_button) && flags.shaded) shade(); } @@ -3066,6 +3231,13 @@ void BlackboxWindow::buttonReleaseEvent(const XButtonEvent *re) { } else { redrawIconifyButton(False); } + } else if (re->window == frame.stick_button && re->button == 1) { + if ((re->x >= 0 && re->x <= static_cast(frame.button_w)) && + (re->y >= 0 && re->y <= static_cast(frame.button_w))) { + stick(); + } else { + redrawStickyButton(False); + } } else if (re->window == frame.close_button & re->button == 1) { if ((re->x >= 0 && re->x <= static_cast(frame.button_w)) && (re->y >= 0 && re->y <= static_cast(frame.button_w))) @@ -3722,11 +3894,14 @@ void BlackboxWindow::motionNotifyEvent(const XMotionEvent *me) { 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 & Button1Mask) && + (me->window == frame.right_grip || + me->window == frame.left_grip)) || ((me->state & Button3Mask) && (me->state & mod_mask) && (frame.title == me->window || frame.label == me->window || - frame.handle == me->window || frame.window == me->window))) { + frame.handle == me->window || frame.window == me->window || + frame.right_grip == me->window || + frame.left_grip == me->window))) { unsigned int zones = screen->getResizeZones(); Corner corner; @@ -3773,10 +3948,15 @@ void BlackboxWindow::enterNotifyEvent(const XCrossingEvent* ce) { bool success = setInputFocus(); if (success) // if focus succeeded install the colormap installColormap(True); // XXX: shouldnt we honour no install? - } - if (screen->doAutoRaise()) - timer->start(); + /* + We only auto-raise when the window wasn't focused because otherwise + we run into problems with gtk+ drop-down lists. The window ends up + raising over the list. + */ + if (screen->doAutoRaise()) + timer->start(); + } } } @@ -4033,13 +4213,17 @@ void BlackboxWindow::constrain(Corner anchor, base_height = (client.base_height) ? client.base_height : client.min_height; - // constrain - 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; - if (dh > client.max_height) dh = client.max_height; - - assert(dw >= base_width && dh >= base_height); + // constrain, but only if the min/max are being used. if they aren't, then + // this resize is going to be from a ConfigureRequest because the window + // isn't allowed to be resized by the user. And in that case, we don't want + // to limit what the app can do + if (client.max_width > client.min_width || + client.max_height > client.min_height) { + 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; + if (dh > client.max_height) dh = client.max_height; + } if (client.width_inc > 1) { dw -= base_width;