X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FScreen.cc;h=6970fdf68111095befb48096e916cf5eadeafc67;hb=733b4f4a3366eca53dc68fd40069b673b0261c96;hp=f4c3dcadbee13b1c2bc5237535b1f0ef38a54dc0;hpb=fb613db29ffcf1539c91f0ac0ca5d25cb4e593b5;p=chaz%2Fopenbox diff --git a/src/Screen.cc b/src/Screen.cc index f4c3dcad..6970fdf6 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -21,12 +21,19 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#ifdef HAVE_CONFIG_H #include "../config.h" +#endif // HAVE_CONFIG_H extern "C" { #include #include +#ifdef XINERAMA +# include +# include +#endif // XINERAMA + #ifdef HAVE_STDLIB_H # include #endif // HAVE_STDLIB_H @@ -83,6 +90,7 @@ using std::string; #include "Window.hh" #include "Workspace.hh" #include "Workspacemenu.hh" +#include "Util.hh" #include "XAtom.hh" #ifndef FONT_ELEMENT_SIZE @@ -151,8 +159,7 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) { XDefineCursor(blackbox->getXDisplay(), getRootWindow(), blackbox->getSessionCursor()); - // start off full screen, top left. - usableArea.setSize(getWidth(), getHeight()); + updateAvailableArea(); image_control = new BImageControl(blackbox, this, True, blackbox->getColorsPerChannel(), @@ -205,7 +212,7 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) { iconmenu = new Iconmenu(this); configmenu = new Configmenu(this); - if (resource.workspaces != 0) { + if (resource.workspaces > 0) { for (unsigned int i = 0; i < resource.workspaces; ++i) { Workspace *wkspc = new Workspace(this, workspacesList.size()); workspacesList.push_back(wkspc); @@ -312,9 +319,6 @@ BScreen::~BScreen(void) { std::for_each(netizenList.begin(), netizenList.end(), PointerAssassin()); - while (! desktopWindowList.empty()) - removeDesktopWindow(desktopWindowList[0]); - while (! systrayWindowList.empty()) removeSystrayWindow(systrayWindowList[0]); @@ -444,6 +448,8 @@ void BScreen::savePlacementPolicy(int p) { const char *placement; switch (resource.placement_policy) { case CascadePlacement: placement = "CascadePlacement"; break; + case UnderMousePlacement: placement = "UnderMousePlacement"; break; + case ClickMousePlacement: placement = "ClickMousePlacement"; break; case ColSmartPlacement: placement = "ColSmartPlacement"; break; case RowSmartPlacement: default: placement = "RowSmartPlacement"; break; } @@ -524,6 +530,20 @@ void BScreen::savePlaceIgnoreMaximized(bool i) { } +void BScreen::saveAllowScrollLock(bool a) { + resource.allow_scroll_lock = a; + config->setValue(screenstr + "disableBindingsWithScrollLock", + resource.allow_scroll_lock); +} + + +void BScreen::saveWorkspaceWarping(bool w) { + resource.workspace_warping = w; + config->setValue(screenstr + "workspaceWarping", + resource.workspace_warping); +} + + void BScreen::save_rc(void) { saveSloppyFocus(resource.sloppy_focus); saveAutoRaise(resource.auto_raise); @@ -550,6 +570,8 @@ void BScreen::save_rc(void) { #endif // HAVE_STRFTIME savePlaceIgnoreShaded(resource.ignore_shaded); savePlaceIgnoreMaximized(resource.ignore_maximized); + saveAllowScrollLock(resource.allow_scroll_lock); + saveWorkspaceWarping(resource.workspace_warping); toolbar->save_rc(); slit->save_rc(); @@ -614,8 +636,9 @@ void BScreen::load_rc(void) { else resource.col_direction = TopBottom; - XAtom::StringVect workspaceNames; if (config->getValue(screenstr + "workspaceNames", s)) { + XAtom::StringVect workspaceNames; + string::const_iterator it = s.begin(), end = s.end(); while(1) { string::const_iterator tmp = it; // current string.begin() @@ -625,9 +648,10 @@ void BScreen::load_rc(void) { break; ++it; } + + xatom->setValue(getRootWindow(), XAtom::net_desktop_names, XAtom::utf8, + workspaceNames); } - xatom->setValue(getRootWindow(), XAtom::net_desktop_names, XAtom::utf8, - workspaceNames); resource.sloppy_focus = true; resource.auto_raise = false; @@ -647,6 +671,10 @@ void BScreen::load_rc(void) { if (config->getValue(screenstr + "windowPlacement", s)) { if (s == "CascadePlacement") resource.placement_policy = CascadePlacement; + else if (s == "UnderMousePlacement") + resource.placement_policy = UnderMousePlacement; + else if (s == "ClickMousePlacement") + resource.placement_policy = ClickMousePlacement; else if (s == "ColSmartPlacement") resource.placement_policy = ColSmartPlacement; else //if (s == "RowSmartPlacement") @@ -678,15 +706,48 @@ void BScreen::load_rc(void) { if (! config->getValue(screenstr + "placementIgnoreMaximized", resource.ignore_maximized)) resource.ignore_maximized = true; + +if (! config->getValue(screenstr + "disableBindingsWithScrollLock", + resource.allow_scroll_lock)) + resource.allow_scroll_lock = false; + + if (! config->getValue(screenstr + "workspaceWarping", + resource.workspace_warping)) + resource.workspace_warping = false; +} + + +void BScreen::changeWorkspaceCount(unsigned int new_count) { + assert(new_count > 0); + + if (new_count < workspacesList.size()) { + // shrink + for (unsigned int i = workspacesList.size(); i > new_count; --i) + removeLastWorkspace(); + // removeLast already sets the current workspace to the + // last available one. + } else if (new_count > workspacesList.size()) { + // grow + for(unsigned int i = workspacesList.size(); i < new_count; ++i) + addWorkspace(); + } } void BScreen::reconfigure(void) { + // don't reconfigure while saving the initial rc file, it's a waste and it + // breaks somethings (workspace names) + if (blackbox->isStartup()) return; + load_rc(); toolbar->load_rc(); slit->load_rc(); LoadStyle(); + // we need to do this explicitly, because just loading this value from the rc + // does nothing + changeWorkspaceCount(resource.workspaces); + XGCValues gcv; gcv.foreground = WhitePixel(blackbox->getXDisplay(), getScreenNumber()); @@ -1162,49 +1223,33 @@ void BScreen::removeSystrayWindow(Window window) { } -void BScreen::addDesktopWindow(Window window) { - desktopWindowList.push_back(window); - XLowerWindow(blackbox->getXDisplay(), window); - XSelectInput(blackbox->getXDisplay(), window, StructureNotifyMask); - blackbox->saveDesktopWindowSearch(window, this); -} - - -void BScreen::removeDesktopWindow(Window window) { - WindowList::iterator it = desktopWindowList.begin(); - const WindowList::iterator end = desktopWindowList.end(); - for (; it != end; ++it) - if (*it == window) { - desktopWindowList.erase(it); - XSelectInput(blackbox->getXDisplay(), window, None); - blackbox->removeDesktopWindowSearch(window); - break; - } -} - - void BScreen::manageWindow(Window w) { + // is the window a KDE systray window? + Window systray; + if (xatom->getValue(w, XAtom::kde_net_wm_system_tray_window_for, + XAtom::window, systray) && systray) { + addSystrayWindow(w); + return; + } + new BlackboxWindow(blackbox, w, this); BlackboxWindow *win = blackbox->searchWindow(w); if (! win) return; - if (win->windowType() == BlackboxWindow::Type_Desktop) { - // desktop windows cant do anything, so we remove all the normal window - // stuff from them, they are only kept around so that we can keep them on - // the bottom of the z-order - win->restore(True); - addDesktopWindow(win->getClientWindow()); - delete win; - return; - } - windowList.push_back(win); - updateClientList(); + + if (win->isNormal()) { + // don't list non-normal windows as managed windows + windowList.push_back(win); + updateClientList(); + } else if (win->isDesktop()) { + desktopWindowList.push_back(win->getFrameWindow()); + } XMapRequestEvent mre; mre.window = w; - if (blackbox->isStartup()) win->restoreAttributes(); + if (blackbox->isStartup() && win->isNormal()) win->restoreAttributes(); win->mapRequestEvent(&mre); } @@ -1212,17 +1257,20 @@ void BScreen::manageWindow(Window w) { void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) { w->restore(remap); - if (w->getWorkspaceNumber() != BSENTINEL && - w->getWindowNumber() != BSENTINEL) - getWorkspace(w->getWorkspaceNumber())->removeWindow(w); - else if (w->isIconic()) - removeIcon(w); - - windowList.remove(w); - updateClientList(); - - if (blackbox->getFocusedWindow() == w) - blackbox->setFocusedWindow((BlackboxWindow *) 0); + if (w->isNormal()) { + // we don't list non-normal windows as managed windows + windowList.remove(w); + updateClientList(); + } else if (w->isDesktop()) { + WindowList::iterator it = desktopWindowList.begin(); + const WindowList::iterator end = desktopWindowList.end(); + for (; it != end; ++it) + if (*it == w->getFrameWindow()) { + desktopWindowList.erase(it); + break; + } + assert(it != end); // the window wasnt a desktop window? + } removeNetizen(w->getClientWindow()); @@ -1354,8 +1402,13 @@ void BScreen::updateNetizenConfigNotify(XEvent *e) { void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) { // the 13 represents the number of blackbox windows such as menus + int bbwins = 13; +#ifdef XINERAMA + ++bbwins; +#endif // XINERAMA + Window *session_stack = new - Window[(num + workspacesList.size() + rootmenuList.size() + 13)]; + Window[(num + workspacesList.size() + rootmenuList.size() + bbwins)]; unsigned int i = 0, k = num; XRaiseWindow(blackbox->getXDisplay(), iconmenu->getWindowID()); @@ -1370,6 +1423,9 @@ void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) { *(session_stack + i++) = configmenu->getFocusmenu()->getWindowID(); *(session_stack + i++) = configmenu->getPlacementmenu()->getWindowID(); +#ifdef XINERAMA + *(session_stack + i++) = configmenu->getXineramamenu()->getWindowID(); +#endif // XINERAMA *(session_stack + i++) = configmenu->getWindowID(); *(session_stack + i++) = slit->getMenu()->getDirectionmenu()->getWindowID(); @@ -2029,10 +2085,28 @@ const Rect& BScreen::availableArea(void) const { } +#ifdef XINERAMA +const RectList& BScreen::allAvailableAreas(void) const { + assert(isXineramaActive()); + assert(xineramaUsableArea.size() > 0); + fprintf(stderr, "1found x %d y %d w %d h %d\n", + xineramaUsableArea[0].x(), xineramaUsableArea[0].y(), + xineramaUsableArea[0].width(), xineramaUsableArea[0].height()); + return xineramaUsableArea; +} +#endif // XINERAMA + + void BScreen::updateAvailableArea(void) { Rect old_area = usableArea; usableArea = getRect(); // reset to full screen +#ifdef XINERAMA + // reset to the full areas + if (isXineramaActive()) + xineramaUsableArea = getXineramaAreas(); +#endif // XINERAMA + /* these values represent offsets from the screen edge * we look for the biggest offset on each edge and then apply them * all at once @@ -2059,6 +2133,27 @@ void BScreen::updateAvailableArea(void) { usableArea.setSize(usableArea.width() - (current_left + current_right), usableArea.height() - (current_top + current_bottom)); +#ifdef XINERAMA + if (isXineramaActive()) { + // keep each of the ximerama-defined areas inside the strut + RectList::iterator xit, xend = xineramaUsableArea.end(); + for (xit = xineramaUsableArea.begin(); xit != xend; ++xit) { + if (xit->x() < usableArea.x()) { + xit->setX(usableArea.x()); + xit->setWidth(xit->width() - usableArea.x()); + } + if (xit->y() < usableArea.y()) { + xit->setY(usableArea.y()); + xit->setHeight(xit->height() - usableArea.y()); + } + if (xit->x() + xit->width() > usableArea.width()) + xit->setWidth(usableArea.width() - xit->x()); + if (xit->y() + xit->height() > usableArea.height()) + xit->setHeight(usableArea.height() - xit->y()); + } + } +#endif // XINERAMA + if (old_area != usableArea) { BlackboxWindowList::iterator it = windowList.begin(), end = windowList.end(); @@ -2143,7 +2238,6 @@ void BScreen::buttonPressEvent(const XButtonEvent *xbutton) { void BScreen::propertyNotifyEvent(const XPropertyEvent *pe) { if (pe->atom == xatom->getAtom(XAtom::net_desktop_names)) { // _NET_WM_DESKTOP_NAMES - fprintf(stderr, "UPDATING WORKSPACE NAMES\n"); WorkspaceList::iterator it = workspacesList.begin(); const WorkspaceList::iterator end = workspacesList.end(); for (; it != end; ++it) {