X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FWindow.cc;h=350552fff40356b9883ea3943bd60df241a9d9d0;hb=db3e93a3c1a57d962741a572a0913ce2555d9dba;hp=60182ce952e38dbccb224df533d8b570792db4f7;hpb=ef66d63b422bd7dc6de9d4dd28b7f7e7c0624e05;p=chaz%2Fopenbox diff --git a/src/Window.cc b/src/Window.cc index 60182ce9..350552ff 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -153,7 +153,7 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { windowmenu = 0; /* - get the initial size and location of client window (relative to the + set the initial size and location of client window (relative to the _root window_). This position is the reference point used with the window's gravity to find the window's initial position. */ @@ -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) { @@ -1005,39 +1005,50 @@ void BlackboxWindow::updateStrut(void) { bool BlackboxWindow::getWindowType(void) { - unsigned long val; + window_type = (WindowType) -1; + + unsigned long *val; + unsigned long num = (unsigned) -1; if (xatom->getValue(client.window, XAtom::net_wm_window_type, XAtom::atom, - val)) { - if (val == xatom->getAtom(XAtom::net_wm_window_type_desktop)) - window_type = Type_Desktop; - else if (val == xatom->getAtom(XAtom::net_wm_window_type_dock)) - window_type = Type_Dock; - else if (val == xatom->getAtom(XAtom::net_wm_window_type_toolbar)) - window_type = Type_Toolbar; - else if (val == xatom->getAtom(XAtom::net_wm_window_type_menu)) - window_type = Type_Menu; - else if (val == xatom->getAtom(XAtom::net_wm_window_type_utility)) - window_type = Type_Utility; - else if (val == xatom->getAtom(XAtom::net_wm_window_type_splash)) - window_type = Type_Splash; - else if (val == xatom->getAtom(XAtom::net_wm_window_type_dialog)) + num, &val)) { + for (unsigned long i = 0; i < num; ++i) { + if (val[i] == xatom->getAtom(XAtom::net_wm_window_type_desktop)) + window_type = Type_Desktop; + else if (val[i] == xatom->getAtom(XAtom::net_wm_window_type_dock)) + window_type = Type_Dock; + else if (val[i] == xatom->getAtom(XAtom::net_wm_window_type_toolbar)) + window_type = Type_Toolbar; + else if (val[i] == xatom->getAtom(XAtom::net_wm_window_type_menu)) + window_type = Type_Menu; + else if (val[i] == xatom->getAtom(XAtom::net_wm_window_type_utility)) + window_type = Type_Utility; + else if (val[i] == xatom->getAtom(XAtom::net_wm_window_type_splash)) + window_type = Type_Splash; + else if (val[i] == xatom->getAtom(XAtom::net_wm_window_type_dialog)) + window_type = Type_Dialog; + else if (val[i] == xatom->getAtom(XAtom::net_wm_window_type_normal)) + window_type = Type_Normal; + else if (val[i] == + xatom->getAtom(XAtom::kde_net_wm_window_type_override)) + mwm_decorations = 0; // prevent this window from getting any decor + } + delete val; + } + + if (window_type == (WindowType) -1) { + /* + * the window type hint was not set, which means we either classify ourself + * as a normal window or a dialog, depending on if we are a transient. + */ + if (isTransient()) window_type = Type_Dialog; - else //if (val[0] == xatom->getAtom(XAtom::net_wm_window_type_normal)) + else window_type = Type_Normal; - return True; + return False; } - /* - * the window type hint was not set, which means we either classify ourself - * as a normal window or a dialog, depending on if we are a transient. - */ - if (isTransient()) - window_type = Type_Dialog; - - window_type = Type_Normal; - - return False; + return True; } @@ -1657,7 +1668,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. @@ -1761,6 +1772,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); @@ -1806,6 +1819,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) @@ -2612,11 +2627,12 @@ void BlackboxWindow::mapRequestEvent(const XMapRequestEvent *re) { #endif // DEBUG /* - Even thought the window wants to be shown, if it is not on the current + 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()) - current_state = WithdrawnState; + if (blackbox_attrib.workspace != screen->getCurrentWorkspaceID() && + blackbox_attrib.workspace < screen->getWorkspaceCount()) + if (current_state == NormalState) current_state = WithdrawnState; switch (current_state) { case IconicState: @@ -2698,10 +2714,10 @@ void BlackboxWindow::reparentNotifyEvent(const XReparentEvent *re) { void BlackboxWindow::propertyNotifyEvent(const XPropertyEvent *pe) { - if (pe->state == PropertyDelete) + if (pe->state == PropertyDelete || ! validateClient()) return; -#ifdef DEBUG +#if 0 fprintf(stderr, "BlackboxWindow::propertyNotifyEvent(): for 0x%lx\n", client.window); #endif @@ -2718,12 +2734,13 @@ void BlackboxWindow::propertyNotifyEvent(const XPropertyEvent *pe) { // determine if this is a transient window getTransientInfo(); + if (flags.stuck != s) stick(); + // adjust the window decorations based on transience if (isTransient()) { functions &= ~Func_Maximize; setAllowedActions(); setupDecor(); - if (flags.stuck != s) stick(); } reconfigure(); @@ -2802,7 +2819,7 @@ void BlackboxWindow::propertyNotifyEvent(const XPropertyEvent *pe) { void BlackboxWindow::exposeEvent(const XExposeEvent *ee) { -#ifdef DEBUG +#if 0 fprintf(stderr, "BlackboxWindow::exposeEvent() for 0x%lx\n", client.window); #endif @@ -3004,6 +3021,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)); /* @@ -3056,13 +3075,12 @@ void BlackboxWindow::doMove(int x_root, int y_root) { dx -= frame.border_w; dy -= frame.border_w; - if (screen->doWorkspaceWarping()) - if (doWorkspaceWarping(x_root, y_root, dx, dy)) - return; - doWindowSnapping(dx, dy); if (screen->doOpaqueMove()) { + if (screen->doWorkspaceWarping()) + doWorkspaceWarping(x_root, y_root, dx); + configure(dx, dy, frame.rect.width(), frame.rect.height()); } else { XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(), @@ -3072,6 +3090,9 @@ void BlackboxWindow::doMove(int x_root, int y_root) { frame.changing.width() - 1, frame.changing.height() - 1); + if (screen->doWorkspaceWarping()) + doWorkspaceWarping(x_root, y_root, dx); + frame.changing.setPos(dx, dy); XDrawRectangle(blackbox->getXDisplay(), screen->getRootWindow(), @@ -3086,8 +3107,7 @@ void BlackboxWindow::doMove(int x_root, int y_root) { } -bool BlackboxWindow::doWorkspaceWarping(int x_root, int y_root, - int dx, int dy) { +void BlackboxWindow::doWorkspaceWarping(int x_root, int y_root, int &dx) { // workspace warping bool warp = False; unsigned int dest = screen->getCurrentWorkspaceID(); @@ -3104,40 +3124,41 @@ bool BlackboxWindow::doWorkspaceWarping(int x_root, int y_root, else dest = 0; } if (! warp) - return false; + return; - endMove(); bool focus = flags.focused; // had focus while moving? - if (! flags.stuck) - screen->reassociateWindow(this, dest, False); - screen->changeWorkspaceID(dest); - if (focus) - setInputFocus(); - /* - We grab the X server here because we are moving the window and then the - mouse cursor. When one moves, it could end up putting the mouse cursor - over another window for a moment. This can cause the warp to iniate a - move on another window. - */ - XGrabServer(blackbox->getXDisplay()); - int dest_x; + int dest_x = x_root; if (x_root <= 0) { - dest_x = screen->getRect().right() - 1; - configure(dx + (screen->getRect().width() - 1), dy, - frame.rect.width(), frame.rect.height()); + dest_x += screen->getRect().width() - 1; + dx += screen->getRect().width() - 1; } else { - dest_x = 0; - configure(dx - (screen->getRect().width() - 1), dy, - frame.rect.width(), frame.rect.height()); + dest_x -= screen->getRect().width() - 1; + dx -= screen->getRect().width() - 1; } + + if (! flags.stuck) + 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, dest_x, y_root); - XUngrabServer(blackbox->getXDisplay()); + XGrabPointer(blackbox->getXDisplay(), frame.window, False, + PointerMotionMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, + None, blackbox->getMoveCursor(), CurrentTime); + + if (screen->doOpaqueMove()) + XUngrabServer(blackbox->getXDisplay()); + + if (focus) + setInputFocus(); - beginMove(dest_x, y_root); - return true; } @@ -3463,11 +3484,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) { @@ -3611,7 +3635,7 @@ void BlackboxWindow::endResize(void) { void BlackboxWindow::motionNotifyEvent(const XMotionEvent *me) { -#ifdef DEBUG +#if 0 fprintf(stderr, "BlackboxWindow::motionNotifyEvent() for 0x%lx\n", client.window); #endif @@ -3673,14 +3697,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(); + } } @@ -3730,6 +3756,12 @@ void BlackboxWindow::restore(bool remap) { if (flags.shaded && ! flags.iconic) setState(NormalState); + // erase the netwm stuff that we read when a window maps, so that it + // doesn't persist between mappings. + // (these are the ones read in getNetWMFlags().) + xatom->eraseValue(client.window, XAtom::net_wm_desktop); + xatom->eraseValue(client.window, XAtom::net_wm_state); + restoreGravity(client.rect); XUnmapWindow(blackbox->getXDisplay(), frame.window);