X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FScreen.cc;h=2722fe4bd28310f1336109fda1ddec2569e830ad;hb=18f704edd0938355622049d853c1ce3cdfaee168;hp=447a7adf543eb28d457a6bbad32fca3e8641cce5;hpb=b9e40b8b1e055baa6a806c56206eb0baccd7ce0a;p=chaz%2Fopenbox diff --git a/src/Screen.cc b/src/Screen.cc index 447a7adf..2722fe4b 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -684,6 +684,8 @@ void BScreen::load_rc(void) { if (! config->getValue(screenstr + "edgeSnapOffset", resource.snap_offset)) resource.snap_offset = 0; + if (resource.snap_offset > 50) // sanity check, setting this huge would + resource.snap_offset = 50; // seriously suck. if (! config->getValue(screenstr + "edgeSnapThreshold", resource.snap_threshold)) @@ -691,7 +693,7 @@ void BScreen::load_rc(void) { if (! config->getValue(screenstr + "resistanceSize", resource.resistance_size)) - resource.resistance_size = 12; + resource.resistance_size = 18; if (config->getValue(screenstr + "rowPlacementDirection", s) && s == "RightToLeft") @@ -972,10 +974,19 @@ void BScreen::LoadStyle(void) { readDatabaseTexture("window.button.unfocus", "black", style); resource.wstyle.b_pressed = readDatabaseTexture("window.button.pressed", "black", style); - resource.wstyle.f_focus = - readDatabaseColor("window.frame.focusColor", "white", style); - resource.wstyle.f_unfocus = - readDatabaseColor("window.frame.unfocusColor", "black", style); + + // we create the window.frame texture by hand because it exists only to + // make the code cleaner and is not actually used for display + BColor color = readDatabaseColor("window.frame.focusColor", "white", style); + resource.wstyle.f_focus = BTexture("solid flat", getBaseDisplay(), + getScreenNumber(), image_control); + resource.wstyle.f_focus.setColor(color); + + color = readDatabaseColor("window.frame.unfocusColor", "white", style); + resource.wstyle.f_unfocus = BTexture("solid flat", getBaseDisplay(), + getScreenNumber(), image_control); + resource.wstyle.f_unfocus.setColor(color); + resource.wstyle.l_text_focus = readDatabaseColor("window.label.focus.textColor", "black", style); resource.wstyle.l_text_unfocus = @@ -993,7 +1004,17 @@ void BScreen::LoadStyle(void) { resource.wstyle.justify = CenterJustify; } - // load toolbar config + // sanity checks + if (resource.wstyle.t_focus.texture() == BTexture::Parent_Relative) + resource.wstyle.t_focus = resource.wstyle.f_focus; + if (resource.wstyle.t_unfocus.texture() == BTexture::Parent_Relative) + resource.wstyle.t_unfocus = resource.wstyle.f_unfocus; + if (resource.wstyle.h_focus.texture() == BTexture::Parent_Relative) + resource.wstyle.h_focus = resource.wstyle.f_focus; + if (resource.wstyle.h_unfocus.texture() == BTexture::Parent_Relative) + resource.wstyle.h_unfocus = resource.wstyle.f_unfocus; + +// load toolbar config resource.tstyle.toolbar = readDatabaseTexture("toolbar", "black", style); resource.tstyle.label = @@ -1023,6 +1044,14 @@ void BScreen::LoadStyle(void) { resource.tstyle.justify = CenterJustify; } + // sanity checks + if (resource.tstyle.toolbar.texture() == BTexture::Parent_Relative) { + resource.tstyle.toolbar = BTexture("solid flat", getBaseDisplay(), + getScreenNumber(), image_control); + resource.tstyle.toolbar.setColor(BColor("black", getBaseDisplay(), + getScreenNumber())); + } + // load menu config resource.mstyle.title = readDatabaseTexture("menu.title", "white", style); @@ -1071,6 +1100,14 @@ void BScreen::LoadStyle(void) { resource.mstyle.bullet_pos = Basemenu::Right; } + // sanity checks + if (resource.mstyle.frame.texture() == BTexture::Parent_Relative) { + resource.mstyle.frame = BTexture("solid flat", getBaseDisplay(), + getScreenNumber(), image_control); + resource.mstyle.frame.setColor(BColor("black", getBaseDisplay(), + getScreenNumber())); + } + resource.border_color = readDatabaseColor("borderColor", "black", style); @@ -1127,7 +1164,8 @@ void BScreen::removeIcon(BlackboxWindow *w) { BlackboxWindow *BScreen::getIcon(unsigned int index) { if (index < iconList.size()) { BlackboxWindowList::iterator it = iconList.begin(); - for (; index > 0; --index, ++it) ; /* increment to index */ + while (index-- > 0) // increment to index + ++it; return *it; } @@ -1194,9 +1232,11 @@ void BScreen::changeWorkspaceID(unsigned int id) { current_workspace->setLastFocusedWindow((BlackboxWindow *) 0); } - // when we switch workspaces, unfocus whatever was focused - blackbox->setFocusedWindow((BlackboxWindow *) 0); - + // when we switch workspaces, unfocus whatever was focused if it is going + // to be unmapped + if (focused && ! focused->isStuck()) + blackbox->setFocusedWindow((BlackboxWindow *) 0); + current_workspace->hideAll(); workspacemenu->setItemSelected(current_workspace->getID() + 2, False); @@ -1210,11 +1250,43 @@ void BScreen::changeWorkspaceID(unsigned int id) { current_workspace->showAll(); - if (resource.focus_last && current_workspace->getLastFocusedWindow()) { - XSync(blackbox->getXDisplay(), False); - current_workspace->getLastFocusedWindow()->setInputFocus(); + int x, y, rx, ry; + Window c, r; + unsigned int m; + BlackboxWindow *win = (BlackboxWindow *) 0; + bool f = False; + + XSync(blackbox->getXDisplay(), False); + + // If sloppy focus and we can find the client window under the pointer, + // try to focus it. + if (resource.sloppy_focus && + XQueryPointer(blackbox->getXDisplay(), getRootWindow(), &r, &c, + &rx, &ry, &x, &y, &m) && + c != None) { + if ( (win = blackbox->searchWindow(c)) ) + f = win->setInputFocus(); } + // If that fails, and we're doing focus_last, try to focus the last window. + if (! f && resource.focus_last && + (win = current_workspace->getLastFocusedWindow())) + f = win->setInputFocus(); + + /* + if we found a focus target, then we set the focused window explicitly + because it is possible to switch off this workspace before the x server + generates the FocusIn event for the window. if that happens, openbox would + lose track of what window was the 'LastFocused' window on the workspace. + + if we did not find a focus target, then set the current focused window to + nothing. + */ + if (f) + blackbox->setFocusedWindow(win); + else + blackbox->setFocusedWindow((BlackboxWindow *) 0); + updateNetizenCurrentWorkspace(); } @@ -1277,15 +1349,22 @@ void BScreen::updateStackingList(void) { void BScreen::addSystrayWindow(Window window) { + XGrabServer(blackbox->getXDisplay()); + + XSelectInput(blackbox->getXDisplay(), window, StructureNotifyMask); systrayWindowList.push_back(window); xatom->setValue(getRootWindow(), XAtom::kde_net_system_tray_windows, XAtom::window, &systrayWindowList[0], systrayWindowList.size()); blackbox->saveSystrayWindowSearch(window, this); + + XUngrabServer(blackbox->getXDisplay()); } void BScreen::removeSystrayWindow(Window window) { + XGrabServer(blackbox->getXDisplay()); + WindowList::iterator it = systrayWindowList.begin(); const WindowList::iterator end = systrayWindowList.end(); for (; it != end; ++it) @@ -1295,8 +1374,13 @@ void BScreen::removeSystrayWindow(Window window) { XAtom::window, &systrayWindowList[0], systrayWindowList.size()); blackbox->removeSystrayWindowSearch(window); + XSelectInput(blackbox->getXDisplay(), window, NoEventMask); break; } + + assert(it != end); // not a systray window + + XUngrabServer(blackbox->getXDisplay()); } @@ -1304,7 +1388,7 @@ 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) { + XAtom::window, systray) && systray != None) { addSystrayWindow(w); return; } @@ -1323,15 +1407,17 @@ void BScreen::manageWindow(Window w) { if (! win) return; - - if (win->isNormal()) { - // don't list non-normal windows as managed windows + if (win->isDesktop()) { + desktopWindowList.push_back(win->getFrameWindow()); + } else { // if (win->isNormal()) { + // don't list desktop windows as managed windows windowList.push_back(win); updateClientList(); - } else if (win->isDesktop()) { - desktopWindowList.push_back(win->getFrameWindow()); + + if (win->isTopmost()) + specialWindowList.push_back(win->getFrameWindow()); } - + XMapRequestEvent mre; mre.window = w; if (blackbox->isStartup() && win->isNormal()) win->restoreAttributes(); @@ -1340,6 +1426,15 @@ void BScreen::manageWindow(Window w) { void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) { + // is the window a KDE systray window? + Window systray; + if (xatom->getValue(w->getClientWindow(), + XAtom::kde_net_wm_system_tray_window_for, + XAtom::window, systray) && systray != None) { + removeSystrayWindow(w->getClientWindow()); + return; + } + w->restore(remap); // Remove the modality so that its parent won't try to re-focus the window @@ -1356,11 +1451,7 @@ void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) { } else if (w->isIconic()) removeIcon(w); - if (w->isNormal()) { - // we don't list non-normal windows as managed windows - windowList.remove(w); - updateClientList(); - } else if (w->isDesktop()) { + if (w->isDesktop()) { WindowList::iterator it = desktopWindowList.begin(); const WindowList::iterator end = desktopWindowList.end(); for (; it != end; ++it) @@ -1369,6 +1460,21 @@ void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) { break; } assert(it != end); // the window wasnt a desktop window? + } else { // if (w->isNormal()) { + // we don't list desktop windows as managed windows + windowList.remove(w); + updateClientList(); + + if (w->isTopmost()) { + WindowList::iterator it = specialWindowList.begin(); + const WindowList::iterator end = specialWindowList.end(); + for (; it != end; ++it) + if (*it == w->getFrameWindow()) { + specialWindowList.erase(it); + break; + } + assert(it != end); // the window wasnt a special window? + } } if (blackbox->getFocusedWindow() == w) @@ -1510,7 +1616,8 @@ void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) { #endif // XINERAMA Window *session_stack = new - Window[(num + workspacesList.size() + rootmenuList.size() + bbwins)]; + Window[(num + workspacesList.size() + rootmenuList.size() + + specialWindowList.size() + bbwins)]; unsigned int i = 0, k = num; XRaiseWindow(blackbox->getXDisplay(), iconmenu->getWindowID()); @@ -1551,6 +1658,10 @@ void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) { if (slit->isOnTop()) *(session_stack + i++) = slit->getWindowID(); + WindowList::iterator sit, send = specialWindowList.end(); + for (sit = specialWindowList.begin(); sit != send; ++sit) + *(session_stack + i++) = *sit; + while (k--) *(session_stack + i++) = *(workspace_stack + k); @@ -1788,12 +1899,13 @@ void BScreen::InitMenu(void) { static -void string_within(char begin, char end, const char *input, size_t length, - char *output) { +size_t string_within(char begin, char end, + const char *input, size_t start_at, size_t length, + char *output) { bool parse = False; size_t index = 0; - - for (size_t i = 0; i < length; ++i) { + size_t i = start_at; + for (; i < length; ++i) { if (input[i] == begin) { parse = True; } else if (input[i] == end) { @@ -1808,6 +1920,8 @@ void string_within(char begin, char end, const char *input, size_t length, output[index] = '\0'; else output[0] = '\0'; + + return i; } @@ -1830,7 +1944,7 @@ bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) { unsigned int key = 0; // get the keyword enclosed in []'s - string_within('[', ']', line, line_length, keyword); + size_t pos = string_within('[', ']', line, 0, line_length, keyword); if (keyword[0] == '\0') { // no keyword, no menu entry continue; @@ -1843,10 +1957,10 @@ bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) { } // get the label enclosed in ()'s - string_within('(', ')', line, line_length, label); + pos = string_within('(', ')', line, pos, line_length, label); // get the command enclosed in {}'s - string_within('{', '}', line, line_length, command); + pos = string_within('{', '}', line, pos, line_length, command); switch (key) { case 311: // end @@ -2107,6 +2221,12 @@ void BScreen::shutdown(void) { while(! windowList.empty()) unmanageWindow(windowList.front(), True); + while(! desktopWindowList.empty()) { + BlackboxWindow *win = blackbox->searchWindow(desktopWindowList.front()); + assert(win); + unmanageWindow(win, True); + } + slit->shutdown(); } @@ -2283,43 +2403,9 @@ void BScreen::buttonPressEvent(const XButtonEvent *xbutton) { if (rootmenu->isVisible()) rootmenu->hide(); } else if (xbutton->button == 2) { - int mx = xbutton->x_root - (workspacemenu->getWidth() / 2); - int my = xbutton->y_root - (workspacemenu->getTitleHeight() / 2); - - if (mx < 0) mx = 0; - if (my < 0) my = 0; - - if (mx + workspacemenu->getWidth() > getWidth()) - mx = getWidth() - workspacemenu->getWidth() - getBorderWidth(); - - if (my + workspacemenu->getHeight() > getHeight()) - my = getHeight() - workspacemenu->getHeight() - getBorderWidth(); - - workspacemenu->move(mx, my); - - if (! workspacemenu->isVisible()) { - workspacemenu->removeParent(); - workspacemenu->show(); - } + showWorkspaceMenu(xbutton->x_root, xbutton->y_root); } else if (xbutton->button == 3) { - int mx = xbutton->x_root - (rootmenu->getWidth() / 2); - int my = xbutton->y_root - (rootmenu->getTitleHeight() / 2); - - if (mx < 0) mx = 0; - if (my < 0) my = 0; - - if (mx + rootmenu->getWidth() > getWidth()) - mx = getWidth() - rootmenu->getWidth() - getBorderWidth(); - - if (my + rootmenu->getHeight() > getHeight()) - my = getHeight() - rootmenu->getHeight() - getBorderWidth(); - - rootmenu->move(mx, my); - - if (! rootmenu->isVisible()) { - blackbox->checkMenu(); - rootmenu->show(); - } + showRootMenu(xbutton->x_root, xbutton->y_root); // mouse wheel up } else if ((xbutton->button == 4 && resource.root_scroll == NormalScroll) || (xbutton->button == 5 && resource.root_scroll == ReverseScroll)) { @@ -2338,6 +2424,50 @@ void BScreen::buttonPressEvent(const XButtonEvent *xbutton) { } +void BScreen::showWorkspaceMenu(int x, int y) { + int mx = x - (workspacemenu->getWidth() / 2); + int my = y - (workspacemenu->getTitleHeight() / 2); + + if (mx < 0) mx = 0; + if (my < 0) my = 0; + + if (mx + workspacemenu->getWidth() > getWidth()) + mx = getWidth() - workspacemenu->getWidth() - getBorderWidth(); + + if (my + workspacemenu->getHeight() > getHeight()) + my = getHeight() - workspacemenu->getHeight() - getBorderWidth(); + + workspacemenu->move(mx, my); + + if (! workspacemenu->isVisible()) { + workspacemenu->removeParent(); + workspacemenu->show(); + } +} + + +void BScreen::showRootMenu(int x, int y) { + int mx = x - (rootmenu->getWidth() / 2); + int my = y - (rootmenu->getTitleHeight() / 2); + + if (mx < 0) mx = 0; + if (my < 0) my = 0; + + if (mx + rootmenu->getWidth() > getWidth()) + mx = getWidth() - rootmenu->getWidth() - getBorderWidth(); + + if (my + rootmenu->getHeight() > getHeight()) + my = getHeight() - rootmenu->getHeight() - getBorderWidth(); + + rootmenu->move(mx, my); + + if (! rootmenu->isVisible()) { + blackbox->checkMenu(); + rootmenu->show(); + } +} + + void BScreen::propertyNotifyEvent(const XPropertyEvent *pe) { if (pe->atom == xatom->getAtom(XAtom::net_desktop_names)) { // _NET_WM_DESKTOP_NAMES @@ -2387,18 +2517,10 @@ BTexture BScreen::readDatabaseTexture(const string &rname, texture.setDisplay(getBaseDisplay(), getScreenNumber()); texture.setImageControl(image_control); - if (texture.texture() & BTexture::Solid) { - texture.setColor(readDatabaseColor(rname + ".color", - default_color, style)); - texture.setColorTo(readDatabaseColor(rname + ".colorTo", - default_color, style)); - } else if (texture.texture() & BTexture::Gradient) { - texture.setColor(readDatabaseColor(rname + ".color", - default_color, style)); - texture.setColorTo(readDatabaseColor(rname + ".colorTo", - default_color, style)); - } - + texture.setColor(readDatabaseColor(rname + ".color", default_color, style)); + texture.setColorTo(readDatabaseColor(rname + ".colorTo", default_color, + style)); + return texture; }