X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FWindow.cc;h=3aabad5268a1caa050e52077de8bc15fd69aa5ea;hb=b48e215ca642d1973e0b1b71e632657c2679443a;hp=a876e110352d5e3c38688cbf49fad1a15046cab4;hpb=6284d4ef9036764d4e6f708ca5f38aa7c1749865;p=chaz%2Fopenbox diff --git a/src/Window.cc b/src/Window.cc index a876e110..3aabad52 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -805,9 +805,10 @@ void BlackboxWindow::positionWindows(void) { XSetWindowBorderWidth(blackbox->getXDisplay(), frame.right_grip, frame.border_w); + // use client.rect here so the value is correct even if shaded XMoveResizeWindow(blackbox->getXDisplay(), frame.handle, -frame.border_w, - frame.rect.height() - frame.margin.bottom + + client.rect.height() + frame.margin.top + frame.mwm_border_w - frame.border_w, frame.inside_w, frame.handle_h); XMoveResizeWindow(blackbox->getXDisplay(), frame.left_grip, @@ -816,6 +817,7 @@ void BlackboxWindow::positionWindows(void) { XMoveResizeWindow(blackbox->getXDisplay(), frame.right_grip, frame.inside_w - frame.grip_w - frame.border_w, -frame.border_w, frame.grip_w, frame.handle_h); + XMapSubwindows(blackbox->getXDisplay(), frame.handle); XMapWindow(blackbox->getXDisplay(), frame.handle); } else if (frame.handle) { @@ -1501,7 +1503,9 @@ void BlackboxWindow::maximize(unsigned int button) { blackbox_attrib.premax_x = frame.rect.x(); blackbox_attrib.premax_y = frame.rect.y(); blackbox_attrib.premax_w = frame.rect.width(); - blackbox_attrib.premax_h = frame.rect.height(); + // use client.rect so that clients can be restored even if shaded + blackbox_attrib.premax_h = + client.rect.height() + frame.margin.top + frame.margin.bottom; const Rect &screen_area = screen->availableArea(); frame.changing = screen_area; @@ -2522,30 +2526,72 @@ void BlackboxWindow::motionNotifyEvent(XMotionEvent *me) { const int snap_distance = screen->getEdgeSnapThreshold(); if (snap_distance) { - Rect srect = screen->availableArea(); // window corners const int wleft = dx, wright = dx + frame.rect.width() - 1, wtop = dy, wbottom = dy + frame.rect.height() - 1; + // Maybe this should be saved in the class, and set in the setWorkspace + // function!! + Workspace *w = screen->getWorkspace(getWorkspaceNumber()); + assert(w); + + // try snap to another window + for (unsigned int i = 0, c = w->getCount(); i < c; ++i) { + BlackboxWindow *snapwin = w->getWindow(i); + if (snapwin == this) + continue; // don't snap to self + + const Rect &winrect = snapwin->frameRect(); + int dleft = std::abs(wright - winrect.left()), + dright = std::abs(wleft - winrect.right()), + dtop = std::abs(wbottom - winrect.top()), + dbottom = std::abs(wtop - winrect.bottom()); + + // snap left? + if (dleft < snap_distance && dleft <= dright) { + dx = winrect.left() - frame.rect.width(); + continue; + } + // snap right? + else if (dright < snap_distance) { + dx = winrect.right() + 1; + continue; + } + + // snap top? + if (dtop < snap_distance && dtop <= dbottom) { + dy = winrect.top() - frame.rect.height(); + continue; + } + // snap bottom? + else if (dbottom < snap_distance) { + dy = winrect.bottom() + 1; + continue; + } + } + + // try snap to the screen's available area + Rect srect = screen->availableArea(); + int dleft = std::abs(wleft - srect.left()), dright = std::abs(wright - srect.right()), dtop = std::abs(wtop - srect.top()), dbottom = std::abs(wbottom - srect.bottom()); // snap left? - if (dleft < snap_distance && dleft < dright) + if (dleft < snap_distance && dleft <= dright) dx = srect.left(); // snap right? - else if (dright < snap_distance && dright < dleft) + else if (dright < snap_distance) dx = srect.right() - frame.rect.width() + 1; // snap top? - if (dtop < snap_distance && dtop < dbottom) + if (dtop < snap_distance && dtop <= dbottom) dy = srect.top(); // snap bottom? - else if (dbottom < snap_distance && dbottom < dtop) + else if (dbottom < snap_distance) dy = srect.bottom() - frame.rect.height() + 1; srect = screen->getRect(); // now get the full screen @@ -2556,17 +2602,17 @@ void BlackboxWindow::motionNotifyEvent(XMotionEvent *me) { dbottom = std::abs(wbottom - srect.bottom()); // snap left? - if (dleft < snap_distance && dleft < dright) + if (dleft < snap_distance && dleft <= dright) dx = srect.left(); // snap right? - else if (dright < snap_distance && dright < dleft) + else if (dright < snap_distance) dx = srect.right() - frame.rect.width() + 1; // snap top? - if (dtop < snap_distance && dtop < dbottom) + if (dtop < snap_distance && dtop <= dbottom) dy = srect.top(); // snap bottom? - else if (dbottom < snap_distance && dbottom < dtop) + else if (dbottom < snap_distance) dy = srect.bottom() - frame.rect.height() + 1; } @@ -2865,13 +2911,23 @@ void BlackboxWindow::upsize(void) { frame.margin.bottom = frame.border_w + frame.mwm_border_w; } - // set the frame rect - frame.rect.setSize(client.rect.width() + frame.margin.left + - frame.margin.right, - client.rect.height() + frame.margin.top + - frame.margin.bottom); - frame.inside_w = frame.rect.width() - (frame.border_w * 2); - frame.inside_h = frame.rect.height() - (frame.border_w * 2); + /* + We first get the normal dimensions and use this to define the inside_w/h + then we modify the height if shading is in effect. + If the shade state is not considered then frame.rect gets reset to the + normal window size on a reconfigure() call resulting in improper + dimensions appearing in move/resize and other events. + */ + unsigned int + height = client.rect.height() + frame.margin.top + frame.margin.bottom, + width = client.rect.width() + frame.margin.left + frame.margin.right; + + frame.inside_w = width - (frame.border_w * 2); + frame.inside_h = height - (frame.border_w * 2); + + if (flags.shaded) + height = frame.title_h + (frame.border_w * 2); + frame.rect.setSize(width, height); } @@ -2881,8 +2937,7 @@ void BlackboxWindow::upsize(void) { * * The logical width and height are placed into pw and ph, if they * are non-zero. Logical size refers to the users perception of - * the window size (for example an xterm has resizes in cells, not in - * pixels). + * the window size (for example an xterm resizes in cells, not in pixels). * * The physical geometry is placed into frame.changing_{x,y,width,height}. * Physical geometry refers to the geometry of the window in pixels. @@ -2978,8 +3033,24 @@ int WindowStyle::doJustify(const char *text, int &start_pos, BWindowGroup::BWindowGroup(Blackbox *b, Window _group) : blackbox(b), group(_group) { - // watch for destroy notify on the group window - XSelectInput(blackbox->getXDisplay(), group, StructureNotifyMask); + XWindowAttributes wattrib; + if (! XGetWindowAttributes(blackbox->getXDisplay(), group, &wattrib)) { + // group window doesn't seem to exist anymore + delete this; + return; + } + + /* + watch for destroy notify on the group window (in addition to + any other events we are looking for) + + since some managed windows can also be window group controllers, + we need to make sure that we don't clobber the event mask for the + managed window + */ + XSelectInput(blackbox->getXDisplay(), group, + wattrib.your_event_mask | StructureNotifyMask); + blackbox->saveGroupSearch(group, this); }