X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FScreen.cc;h=ca94e75a17361192a08442aebf50415ac8f45422;hb=137a0c4e596409a1d35f0f6ea1bd6e4fcd5a3831;hp=27b494af1cb34a8d3e77f1acc085b33dfe0c8222;hpb=0c7e8e4011fad887d42320b269c638369eebcb5e;p=chaz%2Fopenbox diff --git a/src/Screen.cc b/src/Screen.cc index 27b494af..ca94e75a 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -21,19 +21,12 @@ // 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 +#include "../config.h" extern "C" { #include #include -// for strcasestr() -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif // _GNU_SOURCE - #ifdef HAVE_STDLIB_H # include #endif // HAVE_STDLIB_H @@ -68,13 +61,17 @@ extern "C" { #endif // HAVE_STDARG_H } +#include + #include #include +#include using std::string; #include "i18n.hh" #include "blackbox.hh" #include "Clientmenu.hh" +#include "Font.hh" #include "GCCache.hh" #include "Iconmenu.hh" #include "Image.hh" @@ -86,6 +83,7 @@ using std::string; #include "Window.hh" #include "Workspace.hh" #include "Workspacemenu.hh" +#include "XAtom.hh" #ifndef FONT_ELEMENT_SIZE #define FONT_ELEMENT_SIZE 50 @@ -108,6 +106,9 @@ static int anotherWMRunning(Display *display, XErrorEvent *) { BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) { blackbox = bb; + screenstr = "session.screen" + itostring(scrn) + '.'; + config = blackbox->getConfig(); + xatom = blackbox->getXAtom(); event_mask = ColormapChangeMask | EnterWindowMask | PropertyChangeMask | SubstructureRedirectMask | ButtonPressMask | ButtonReleaseMask; @@ -127,21 +128,25 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) { getDepth()); rootmenu = 0; - resource.stylerc = 0; - resource.mstyle.t_fontset = resource.mstyle.f_fontset = - resource.tstyle.fontset = resource.wstyle.fontset = (XFontSet) 0; resource.mstyle.t_font = resource.mstyle.f_font = resource.tstyle.font = - resource.wstyle.font = (XFontStruct *) 0; + resource.wstyle.font = (BFont *) 0; -#ifdef HAVE_GETPID - pid_t bpid = getpid(); + geom_pixmap = None; - XChangeProperty(blackbox->getXDisplay(), getRootWindow(), - blackbox->getBlackboxPidAtom(), XA_CARDINAL, - sizeof(pid_t) * 8, PropModeReplace, - (unsigned char *) &bpid, 1); + xatom->setSupported(this); // set-up netwm support +#ifdef HAVE_GETPID + xatom->setValue(getRootWindow(), XAtom::blackbox_pid, XAtom::cardinal, + (unsigned long) getpid()); #endif // HAVE_GETPID + unsigned long geometry[] = { getWidth(), + getHeight()}; + xatom->setValue(getRootWindow(), XAtom::net_desktop_geometry, + XAtom::cardinal, geometry, 2); + unsigned long viewport[] = {0,0}; + xatom->setValue(getRootWindow(), XAtom::net_desktop_viewport, + XAtom::cardinal, viewport, 2); + XDefineCursor(blackbox->getXDisplay(), getRootWindow(), blackbox->getSessionCursor()); @@ -155,16 +160,10 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) { image_control->installRootColormap(); root_colormap_installed = True; - blackbox->load_rc(this); - - image_control->setDither(resource.image_dither); - + load_rc(); LoadStyle(); XGCValues gcv; - unsigned long gc_value_mask = GCForeground; - if (! i18n.multibyte()) gc_value_mask |= GCFont; - gcv.foreground = WhitePixel(blackbox->getXDisplay(), getScreenNumber()) ^ BlackPixel(blackbox->getXDisplay(), getScreenNumber()); gcv.function = GXxor; @@ -174,23 +173,8 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) { const char *s = i18n(ScreenSet, ScreenPositionLength, "0: 0000 x 0: 0000"); - int l = strlen(s); - - if (i18n.multibyte()) { - XRectangle ink, logical; - XmbTextExtents(resource.wstyle.fontset, s, l, &ink, &logical); - geom_w = logical.width; - - geom_h = resource.wstyle.fontset_extents->max_ink_extent.height; - } else { - geom_h = resource.wstyle.font->ascent + - resource.wstyle.font->descent; - - geom_w = XTextWidth(resource.wstyle.font, s, l); - } - - geom_w += (resource.bevel_width * 2); - geom_h += (resource.bevel_width * 2); + geom_w = resource.wstyle.font->measureString(s) + resource.bevel_width * 2; + geom_h = resource.wstyle.font->height() + resource.bevel_width * 2; XSetWindowAttributes attrib; unsigned long mask = CWBorderPixel | CWColormap | CWSaveUnder; @@ -233,11 +217,18 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) { workspacesList.push_back(wkspc); workspacemenu->insert(wkspc->getName(), wkspc->getMenu()); } + saveWorkspaceNames(); + + updateNetizenWorkspaceCount(); workspacemenu->insert(i18n(IconSet, IconIcons, "Icons"), iconmenu); workspacemenu->update(); current_workspace = workspacesList.front(); + + xatom->setValue(getRootWindow(), XAtom::net_current_desktop, + XAtom::cardinal, 0); //first workspace + workspacemenu->setItemSelected(2, True); toolbar = new Toolbar(this); @@ -246,9 +237,10 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) { InitMenu(); - raiseWindows(0, 0); + raiseWindows(0, 0); // this also initializes the empty stacking list rootmenu->update(); + updateClientList(); // initialize the client list, which will be empty updateAvailableArea(); changeWorkspaceID(0); @@ -326,40 +318,326 @@ BScreen::~BScreen(void) { delete toolbar; delete image_control; - if (resource.wstyle.fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.wstyle.fontset); - if (resource.mstyle.t_fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.mstyle.t_fontset); - if (resource.mstyle.f_fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.mstyle.f_fontset); - if (resource.tstyle.fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.tstyle.fontset); - if (resource.wstyle.font) - XFreeFont(blackbox->getXDisplay(), resource.wstyle.font); + delete resource.wstyle.font; if (resource.mstyle.t_font) - XFreeFont(blackbox->getXDisplay(), resource.mstyle.t_font); + delete resource.mstyle.t_font; if (resource.mstyle.f_font) - XFreeFont(blackbox->getXDisplay(), resource.mstyle.f_font); + delete resource.mstyle.f_font; if (resource.tstyle.font) - XFreeFont(blackbox->getXDisplay(), resource.tstyle.font); + delete resource.tstyle.font; XFreeGC(blackbox->getXDisplay(), opGC); } -void BScreen::removeWorkspaceNames(void) { - workspaceNames.clear(); +void BScreen::saveSloppyFocus(bool s) { + resource.sloppy_focus = s; + + string fmodel; + if (resource.sloppy_focus) { + fmodel = "SloppyFocus"; + if (resource.auto_raise) fmodel += " AutoRaise"; + if (resource.click_raise) fmodel += " ClickRaise"; + } else { + fmodel = "ClickToFocus"; + } + config->setValue(screenstr + "focusModel", fmodel); +} + + +void BScreen::saveAutoRaise(bool a) { + resource.auto_raise = a; + saveSloppyFocus(resource.sloppy_focus); +} + + +void BScreen::saveClickRaise(bool c) { + resource.click_raise = c; + saveSloppyFocus(resource.sloppy_focus); +} + + +void BScreen::saveImageDither(bool d) { + image_control->setDither(d); + config->setValue(screenstr + "imageDither", doImageDither()); +} + + +void BScreen::saveOpaqueMove(bool o) { + resource.opaque_move = o; + config->setValue(screenstr + "opaqueMove", resource.opaque_move); +} + + +void BScreen::saveFullMax(bool f) { + resource.full_max = f; + config->setValue(screenstr + "fullMaximization", resource.full_max); +} + + +void BScreen::saveFocusNew(bool f) { + resource.focus_new = f; + config->setValue(screenstr + "focusNewWindows", resource.focus_new); +} + + +void BScreen::saveFocusLast(bool f) { + resource.focus_last = f; + config->setValue(screenstr + "focusLastWindow", resource.focus_last); +} + + +void BScreen::saveHideToolbar(bool h) { + resource.hide_toolbar = h; + if (resource.hide_toolbar) + toolbar->unmapToolbar(); + else + toolbar->mapToolbar(); + config->setValue(screenstr + "hideToolbar", resource.hide_toolbar); +} + + +void BScreen::saveWindowToWindowSnap(bool s) { + resource.window_to_window_snap = s; + config->setValue(screenstr + "windowToWindowSnap", + resource.window_to_window_snap); +} + + +void BScreen::saveWindowCornerSnap(bool s) { + resource.window_corner_snap = s; + config->setValue(screenstr + "windowCornerSnap", + resource.window_corner_snap); +} + + +void BScreen::saveWorkspaces(unsigned int w) { + resource.workspaces = w; + config->setValue(screenstr + "workspaces", resource.workspaces); +} + + +void BScreen::savePlacementPolicy(int p) { + resource.placement_policy = p; + const char *placement; + switch (resource.placement_policy) { + case CascadePlacement: placement = "CascadePlacement"; break; + case ColSmartPlacement: placement = "ColSmartPlacement"; break; + case RowSmartPlacement: default: placement = "RowSmartPlacement"; break; + } + config->setValue(screenstr + "windowPlacement", placement); +} + + +void BScreen::saveEdgeSnapThreshold(int t) { + resource.edge_snap_threshold = t; + config->setValue(screenstr + "edgeSnapThreshold", + resource.edge_snap_threshold); +} + + +void BScreen::saveRowPlacementDirection(int d) { + resource.row_direction = d; + config->setValue(screenstr + "rowPlacementDirection", + resource.row_direction == LeftRight ? + "LeftToRight" : "RightToLeft"); +} + + +void BScreen::saveColPlacementDirection(int d) { + resource.col_direction = d; + config->setValue(screenstr + "colPlacementDirection", + resource.col_direction == TopBottom ? + "TopToBottom" : "BottomToTop"); +} + + +#ifdef HAVE_STRFTIME +void BScreen::saveStrftimeFormat(const std::string& format) { + resource.strftime_format = format; + config->setValue(screenstr + "strftimeFormat", resource.strftime_format); +} + +#else // !HAVE_STRFTIME + +void BScreen::saveDateFormat(int f) { + resource.date_format = f; + config->setValue(screenstr + "dateFormat", + resource.date_format == B_EuropeanDate ? + "European" : "American"); +} + + +void BScreen::saveClock24Hour(Bool c) { + resource.clock24hour = c; + config->setValue(screenstr + "clockFormat", resource.clock24hour ? 24 : 12); +} +#endif // HAVE_STRFTIME + + +void BScreen::saveWorkspaceNames() { + XAtom::StringVect nameList; + unsigned long numnames = (unsigned) -1; + string names; + + if (numnames > 0 && + xatom->getValue(getRootWindow(), XAtom::net_desktop_names, XAtom::utf8, + numnames, nameList)) { + for (unsigned int i = 0; i < nameList.size(); ++i) { + if (i > 0) names += ","; + names += nameList[i]; + } + } + config->setValue(screenstr + "workspaceNames", names); +} + + +void BScreen::save_rc(void) { + saveSloppyFocus(resource.sloppy_focus); + saveAutoRaise(resource.auto_raise); + saveImageDither(doImageDither()); + saveOpaqueMove(resource.opaque_move); + saveFullMax(resource.full_max); + saveFocusNew(resource.focus_new); + saveFocusLast(resource.focus_last); + saveHideToolbar(resource.hide_toolbar); + saveWindowToWindowSnap(resource.window_to_window_snap); + saveWindowCornerSnap(resource.window_corner_snap); + saveWorkspaces(resource.workspaces); + savePlacementPolicy(resource.placement_policy); + saveEdgeSnapThreshold(resource.edge_snap_threshold); + saveRowPlacementDirection(resource.row_direction); + saveColPlacementDirection(resource.col_direction); +#ifdef HAVE_STRFTIME + saveStrftimeFormat(resource.strftime_format); +#else // !HAVE_STRFTIME + saveDateFormat(resource.date_format); + savwClock24Hour(resource.clock24hour); +#endif // HAVE_STRFTIME + + toolbar->save_rc(); + slit->save_rc(); +} + + +void BScreen::load_rc(void) { + std::string s; + bool b; + + if (! config->getValue(screenstr + "fullMaximization", resource.full_max)) + resource.full_max = false; + + if (! config->getValue(screenstr + "focusNewWindows", resource.focus_new)) + resource.focus_new = false; + + if (! config->getValue(screenstr + "focusLastWindow", resource.focus_last)) + resource.focus_last = false; + + if (! config->getValue(screenstr + "workspaces", resource.workspaces)) + resource.workspaces = 1; + + if (! config->getValue(screenstr + "opaqueMove", resource.opaque_move)) + resource.opaque_move = false; + + if (! config->getValue(screenstr + "hideToolbar", resource.hide_toolbar)) + resource.hide_toolbar = false; + + if (! config->getValue(screenstr + "windowToWindowSnap", + resource.window_to_window_snap)) + resource.window_to_window_snap = true; + + if (! config->getValue(screenstr + "windowCornerSnap", + resource.window_corner_snap)) + resource.window_corner_snap = true; + + if (! config->getValue(screenstr + "imageDither", b)) + b = true; + image_control->setDither(b); + + if (! config->getValue(screenstr + "edgeSnapThreshold", + resource.edge_snap_threshold)) + resource.edge_snap_threshold = 4; + + if (config->getValue(screenstr + "rowPlacementDirection", s) && + s == "RightToLeft") + resource.row_direction = RightLeft; + else + resource.row_direction = LeftRight; + + if (config->getValue(screenstr + "colPlacementDirection", s) && + s == "BottomToTop") + resource.col_direction = BottomTop; + else + resource.col_direction = TopBottom; + + XAtom::StringVect workspaceNames; + if (config->getValue(screenstr + "workspaceNames", s)) { + string::const_iterator it = s.begin(), end = s.end(); + while(1) { + string::const_iterator tmp = it; // current string.begin() + it = std::find(tmp, end, ','); // look for comma between tmp and end + workspaceNames.push_back(string(tmp, it)); // s[tmp:it] + if (it == end) + break; + ++it; + } + } + xatom->setValue(getRootWindow(), XAtom::net_desktop_names, XAtom::utf8, + workspaceNames); + + resource.sloppy_focus = true; + resource.auto_raise = false; + resource.click_raise = false; + if (config->getValue(screenstr + "focusModel", s)) { + if (s.find("ClickToFocus") != string::npos) { + resource.sloppy_focus = false; + } else { + // must be sloppy + if (s.find("AutoRaise") != string::npos) + resource.auto_raise = true; + if (s.find("ClickRaise") != string::npos) + resource.click_raise = true; + } + } + + if (config->getValue(screenstr + "windowPlacement", s)) { + if (s == "CascadePlacement") + resource.placement_policy = CascadePlacement; + else if (s == "ColSmartPlacement") + resource.placement_policy = ColSmartPlacement; + else //if (s == "RowSmartPlacement") + resource.placement_policy = RowSmartPlacement; + } else + resource.placement_policy = RowSmartPlacement; + +#ifdef HAVE_STRFTIME + if (config->getValue(screenstr + "strftimeFormat", s)) + resource.strftime_format = s; + else + resource.strftime_format = "%I:%M %p"; +#else // !HAVE_STRFTIME + long l; + + if (config->getValue(screenstr + "dateFormat", s) && s == "European") + resource.date_format = B_EuropeanDate; + else + resource.date_format = B_AmericanDate; + + if (! config->getValue(screenstr + "clockFormat", l)) + l = 12; + resource.clock24hour = l == 24; +#endif // HAVE_STRFTIME } void BScreen::reconfigure(void) { + load_rc(); + toolbar->load_rc(); + slit->load_rc(); LoadStyle(); XGCValues gcv; - unsigned long gc_value_mask = GCForeground; - if (! i18n.multibyte()) gc_value_mask |= GCFont; - gcv.foreground = WhitePixel(blackbox->getXDisplay(), getScreenNumber()); gcv.function = GXinvert; @@ -369,22 +647,9 @@ void BScreen::reconfigure(void) { const char *s = i18n(ScreenSet, ScreenPositionLength, "0: 0000 x 0: 0000"); - int l = strlen(s); - if (i18n.multibyte()) { - XRectangle ink, logical; - XmbTextExtents(resource.wstyle.fontset, s, l, &ink, &logical); - geom_w = logical.width; - - geom_h = resource.wstyle.fontset_extents->max_ink_extent.height; - } else { - geom_w = XTextWidth(resource.wstyle.font, s, l); - - geom_h = resource.wstyle.font->ascent + resource.wstyle.font->descent; - } - - geom_w += (resource.bevel_width * 2); - geom_h += (resource.bevel_width * 2); + geom_w = resource.wstyle.font->measureString(s) + resource.bevel_width * 2; + geom_h = resource.wstyle.font->height() + resource.bevel_width * 2; BTexture* texture = &(resource.wstyle.l_focus); geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap); @@ -407,11 +672,31 @@ void BScreen::reconfigure(void) { workspacemenu->reconfigure(); iconmenu->reconfigure(); - int remember_sub = rootmenu->getCurrentSubmenu(); + typedef std::vector SubList; + SubList remember_subs; + + // save the current open menus + Basemenu *menu = rootmenu; + int submenu; + while ((submenu = menu->getCurrentSubmenu()) >= 0) { + remember_subs.push_back(submenu); + menu = menu->find(submenu)->submenu(); + assert(menu); + } + InitMenu(); raiseWindows(0, 0); rootmenu->reconfigure(); - rootmenu->drawSubmenu(remember_sub); + + // reopen the saved menus + menu = rootmenu; + const SubList::iterator subs_end = remember_subs.end(); + for (SubList::iterator it = remember_subs.begin(); it != subs_end; ++it) { + menu->drawSubmenu(*it); + menu = menu->find(*it)->submenu(); + if (! menu) + break; + } configmenu->reconfigure(); @@ -442,259 +727,183 @@ void BScreen::rereadMenu(void) { void BScreen::LoadStyle(void) { - resource.stylerc = XrmGetFileDatabase(blackbox->getStyleFilename()); - if (! resource.stylerc) - resource.stylerc = XrmGetFileDatabase(DEFAULTSTYLE); + Configuration style(False); + + const char *sfile = blackbox->getStyleFilename(); + if (sfile != NULL) { + style.setFile(sfile); + if (! style.load()) { + style.setFile(DEFAULTSTYLE); + if (! style.load()) + style.create(); // hardcoded default values will be used. + } + } + + // merge in the rc file + style.merge(config->file(), True); - XrmValue value; - char *value_type; + string s; // load fonts/fontsets - if (resource.wstyle.fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.wstyle.fontset); - if (resource.tstyle.fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.tstyle.fontset); - if (resource.mstyle.f_fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.mstyle.f_fontset); - if (resource.mstyle.t_fontset) - XFreeFontSet(blackbox->getXDisplay(), resource.mstyle.t_fontset); - resource.wstyle.fontset = 0; - resource.tstyle.fontset = 0; - resource.mstyle.f_fontset = 0; - resource.mstyle.t_fontset = 0; if (resource.wstyle.font) - XFreeFont(blackbox->getXDisplay(), resource.wstyle.font); + delete resource.wstyle.font; if (resource.tstyle.font) - XFreeFont(blackbox->getXDisplay(), resource.tstyle.font); + delete resource.tstyle.font; if (resource.mstyle.f_font) - XFreeFont(blackbox->getXDisplay(), resource.mstyle.f_font); + delete resource.mstyle.f_font; if (resource.mstyle.t_font) - XFreeFont(blackbox->getXDisplay(), resource.mstyle.t_font); - resource.wstyle.font = 0; - resource.tstyle.font = 0; - resource.mstyle.f_font = 0; - resource.mstyle.t_font = 0; - - if (i18n.multibyte()) { - resource.wstyle.fontset = - readDatabaseFontSet("window.font", "Window.Font"); - resource.tstyle.fontset = - readDatabaseFontSet("toolbar.font", "Toolbar.Font"); - resource.mstyle.t_fontset = - readDatabaseFontSet("menu.title.font", "Menu.Title.Font"); - resource.mstyle.f_fontset = - readDatabaseFontSet("menu.frame.font", "Menu.Frame.Font"); - - resource.mstyle.t_fontset_extents = - XExtentsOfFontSet(resource.mstyle.t_fontset); - resource.mstyle.f_fontset_extents = - XExtentsOfFontSet(resource.mstyle.f_fontset); - resource.tstyle.fontset_extents = - XExtentsOfFontSet(resource.tstyle.fontset); - resource.wstyle.fontset_extents = - XExtentsOfFontSet(resource.wstyle.fontset); - } else { - resource.wstyle.font = - readDatabaseFont("window.font", "Window.Font"); - resource.tstyle.font = - readDatabaseFont("toolbar.font", "Toolbar.Font"); - resource.mstyle.t_font = - readDatabaseFont("menu.title.font", "Menu.Title.Font"); - resource.mstyle.f_font = - readDatabaseFont("menu.frame.font", "Menu.Frame.Font"); - } + delete resource.mstyle.t_font; + resource.wstyle.font = resource.tstyle.font = resource.mstyle.f_font = + resource.mstyle.t_font = (BFont *) 0; + + resource.wstyle.font = readDatabaseFont("window.font", style); + resource.tstyle.font = readDatabaseFont("toolbar.font", style); + resource.mstyle.t_font = readDatabaseFont("menu.title.font", style); + resource.mstyle.f_font = readDatabaseFont("menu.frame.font", style); // load window config resource.wstyle.t_focus = - readDatabaseTexture("window.title.focus", "Window.Title.Focus", "white"); + readDatabaseTexture("window.title.focus", "white", style); resource.wstyle.t_unfocus = - readDatabaseTexture("window.title.unfocus", - "Window.Title.Unfocus", "black"); + readDatabaseTexture("window.title.unfocus", "black", style); resource.wstyle.l_focus = - readDatabaseTexture("window.label.focus", "Window.Label.Focus", "white" ); + readDatabaseTexture("window.label.focus", "white", style); resource.wstyle.l_unfocus = - readDatabaseTexture("window.label.unfocus", "Window.Label.Unfocus", - "black"); + readDatabaseTexture("window.label.unfocus", "black", style); resource.wstyle.h_focus = - readDatabaseTexture("window.handle.focus", "Window.Handle.Focus", "white"); + readDatabaseTexture("window.handle.focus", "white", style); resource.wstyle.h_unfocus = - readDatabaseTexture("window.handle.unfocus", - "Window.Handle.Unfocus", "black"); + readDatabaseTexture("window.handle.unfocus", "black", style); resource.wstyle.g_focus = - readDatabaseTexture("window.grip.focus", "Window.Grip.Focus", "white"); + readDatabaseTexture("window.grip.focus", "white", style); resource.wstyle.g_unfocus = - readDatabaseTexture("window.grip.unfocus", "Window.Grip.Unfocus", "black"); + readDatabaseTexture("window.grip.unfocus", "black", style); resource.wstyle.b_focus = - readDatabaseTexture("window.button.focus", "Window.Button.Focus", "white"); + readDatabaseTexture("window.button.focus", "white", style); resource.wstyle.b_unfocus = - readDatabaseTexture("window.button.unfocus", - "Window.Button.Unfocus", "black"); + readDatabaseTexture("window.button.unfocus", "black", style); resource.wstyle.b_pressed = - readDatabaseTexture("window.button.pressed", - "Window.Button.Pressed", "black"); + readDatabaseTexture("window.button.pressed", "black", style); resource.wstyle.f_focus = - readDatabaseColor("window.frame.focusColor", - "Window.Frame.FocusColor", "white"); + readDatabaseColor("window.frame.focusColor", "white", style); resource.wstyle.f_unfocus = - readDatabaseColor("window.frame.unfocusColor", - "Window.Frame.UnfocusColor", "black"); + readDatabaseColor("window.frame.unfocusColor", "black", style); resource.wstyle.l_text_focus = - readDatabaseColor("window.label.focus.textColor", - "Window.Label.Focus.TextColor", "black"); + readDatabaseColor("window.label.focus.textColor", "black", style); resource.wstyle.l_text_unfocus = - readDatabaseColor("window.label.unfocus.textColor", - "Window.Label.Unfocus.TextColor", "white"); + readDatabaseColor("window.label.unfocus.textColor", "white", style); resource.wstyle.b_pic_focus = - readDatabaseColor("window.button.focus.picColor", - "Window.Button.Focus.PicColor", "black"); + readDatabaseColor("window.button.focus.picColor", "black", style); resource.wstyle.b_pic_unfocus = - readDatabaseColor("window.button.unfocus.picColor", - "Window.Button.Unfocus.PicColor", "white"); + readDatabaseColor("window.button.unfocus.picColor", "white", style); resource.wstyle.justify = LeftJustify; - if (XrmGetResource(resource.stylerc, "window.justify", "Window.Justify", - &value_type, &value)) { - if (strstr(value.addr, "right") || strstr(value.addr, "Right")) + if (style.getValue("window.justify", s)) { + if (s == "right" || s == "Right") resource.wstyle.justify = RightJustify; - else if (strstr(value.addr, "center") || strstr(value.addr, "Center")) + else if (s == "center" || s == "Center") resource.wstyle.justify = CenterJustify; } // load toolbar config resource.tstyle.toolbar = - readDatabaseTexture("toolbar", "Toolbar", "black"); + readDatabaseTexture("toolbar", "black", style); resource.tstyle.label = - readDatabaseTexture("toolbar.label", "Toolbar.Label", "black"); + readDatabaseTexture("toolbar.label", "black", style); resource.tstyle.window = - readDatabaseTexture("toolbar.windowLabel", "Toolbar.WindowLabel", "black"); + readDatabaseTexture("toolbar.windowLabel", "black", style); resource.tstyle.button = - readDatabaseTexture("toolbar.button", "Toolbar.Button", "white"); + readDatabaseTexture("toolbar.button", "white", style); resource.tstyle.pressed = - readDatabaseTexture("toolbar.button.pressed", - "Toolbar.Button.Pressed", "black"); + readDatabaseTexture("toolbar.button.pressed", "black", style); resource.tstyle.clock = - readDatabaseTexture("toolbar.clock", "Toolbar.Clock", "black"); + readDatabaseTexture("toolbar.clock", "black", style); resource.tstyle.l_text = - readDatabaseColor("toolbar.label.textColor", - "Toolbar.Label.TextColor", "white"); + readDatabaseColor("toolbar.label.textColor", "white", style); resource.tstyle.w_text = - readDatabaseColor("toolbar.windowLabel.textColor", - "Toolbar.WindowLabel.TextColor", "white"); + readDatabaseColor("toolbar.windowLabel.textColor", "white", style); resource.tstyle.c_text = - readDatabaseColor("toolbar.clock.textColor", - "Toolbar.Clock.TextColor", "white"); + readDatabaseColor("toolbar.clock.textColor", "white", style); resource.tstyle.b_pic = - readDatabaseColor("toolbar.button.picColor", - "Toolbar.Button.PicColor", "black"); + readDatabaseColor("toolbar.button.picColor", "black", style); resource.tstyle.justify = LeftJustify; - if (XrmGetResource(resource.stylerc, "toolbar.justify", - "Toolbar.Justify", &value_type, &value)) { - if (strstr(value.addr, "right") || strstr(value.addr, "Right")) + if (style.getValue("toolbar.justify", s)) { + if (s == "right" || s == "Right") resource.tstyle.justify = RightJustify; - else if (strstr(value.addr, "center") || strstr(value.addr, "Center")) + else if (s == "center" || s == "Center") resource.tstyle.justify = CenterJustify; } // load menu config resource.mstyle.title = - readDatabaseTexture("menu.title", "Menu.Title", "white"); + readDatabaseTexture("menu.title", "white", style); resource.mstyle.frame = - readDatabaseTexture("menu.frame", "Menu.Frame", "black"); + readDatabaseTexture("menu.frame", "black", style); resource.mstyle.hilite = - readDatabaseTexture("menu.hilite", "Menu.Hilite", "white"); + readDatabaseTexture("menu.hilite", "white", style); resource.mstyle.t_text = - readDatabaseColor("menu.title.textColor", "Menu.Title.TextColor", "black"); + readDatabaseColor("menu.title.textColor", "black", style); resource.mstyle.f_text = - readDatabaseColor("menu.frame.textColor", "Menu.Frame.TextColor", "white"); + readDatabaseColor("menu.frame.textColor", "white", style); resource.mstyle.d_text = - readDatabaseColor("menu.frame.disableColor", - "Menu.Frame.DisableColor", "black"); + readDatabaseColor("menu.frame.disableColor", "black", style); resource.mstyle.h_text = - readDatabaseColor("menu.hilite.textColor", - "Menu.Hilite.TextColor", "black"); + readDatabaseColor("menu.hilite.textColor", "black", style); resource.mstyle.t_justify = LeftJustify; - if (XrmGetResource(resource.stylerc, "menu.title.justify", - "Menu.Title.Justify", - &value_type, &value)) { - if (strstr(value.addr, "right") || strstr(value.addr, "Right")) + if (style.getValue("menu.title.justify", s)) { + if (s == "right" || s == "Right") resource.mstyle.t_justify = RightJustify; - else if (strstr(value.addr, "center") || strstr(value.addr, "Center")) + else if (s == "center" || s == "Center") resource.mstyle.t_justify = CenterJustify; } resource.mstyle.f_justify = LeftJustify; - if (XrmGetResource(resource.stylerc, "menu.frame.justify", - "Menu.Frame.Justify", - &value_type, &value)) { - if (strstr(value.addr, "right") || strstr(value.addr, "Right")) + if (style.getValue("menu.frame.justify", s)) { + if (s == "right" || s == "Right") resource.mstyle.f_justify = RightJustify; - else if (strstr(value.addr, "center") || strstr(value.addr, "Center")) + else if (s == "center" || s == "Center") resource.mstyle.f_justify = CenterJustify; } resource.mstyle.bullet = Basemenu::Triangle; - if (XrmGetResource(resource.stylerc, "menu.bullet", "Menu.Bullet", - &value_type, &value)) { - if (! strncasecmp(value.addr, "empty", value.size)) + if (style.getValue("menu.bullet", s)) { + if (s == "empty" || s == "Empty") resource.mstyle.bullet = Basemenu::Empty; - else if (! strncasecmp(value.addr, "square", value.size)) + else if (s == "square" || s == "Square") resource.mstyle.bullet = Basemenu::Square; - else if (! strncasecmp(value.addr, "diamond", value.size)) + else if (s == "diamond" || s == "Diamond") resource.mstyle.bullet = Basemenu::Diamond; } resource.mstyle.bullet_pos = Basemenu::Left; - if (XrmGetResource(resource.stylerc, "menu.bullet.position", - "Menu.Bullet.Position", &value_type, &value)) { - if (! strncasecmp(value.addr, "right", value.size)) + if (style.getValue("menu.bullet.position", s)) { + if (s == "right" || s == "Right") resource.mstyle.bullet_pos = Basemenu::Right; } resource.border_color = - readDatabaseColor("borderColor", "BorderColor", "black"); - - unsigned int uint_value; + readDatabaseColor("borderColor", "black", style); // load bevel, border and handle widths - resource.handle_width = 6; - if (XrmGetResource(resource.stylerc, "handleWidth", "HandleWidth", - &value_type, &value) && - sscanf(value.addr, "%u", &uint_value) == 1 && - uint_value <= (getWidth() / 2) && uint_value != 0) { - resource.handle_width = uint_value; - } - - resource.border_width = 1; - if (XrmGetResource(resource.stylerc, "borderWidth", "BorderWidth", - &value_type, &value) && - sscanf(value.addr, "%u", &uint_value) == 1) { - resource.border_width = uint_value; - } + if (! style.getValue("handleWidth", resource.handle_width) || + resource.handle_width > (getWidth() / 2) || resource.handle_width == 0) + resource.handle_width = 6; - resource.bevel_width = 3; - if (XrmGetResource(resource.stylerc, "bevelWidth", "BevelWidth", - &value_type, &value) && - sscanf(value.addr, "%u", &uint_value) == 1 && - uint_value <= (getWidth() / 2) && uint_value != 0) { - resource.bevel_width = uint_value; - } + if (! style.getValue("borderWidth", resource.border_width)) + resource.border_width = 1; - resource.frame_width = resource.bevel_width; - if (XrmGetResource(resource.stylerc, "frameWidth", "FrameWidth", - &value_type, &value) && - sscanf(value.addr, "%u", &uint_value) == 1 && - uint_value <= (getWidth() / 2)) { - resource.frame_width = uint_value; - } + if (! style.getValue("bevelWidth", resource.bevel_width) || + resource.bevel_width > (getWidth() / 2) || resource.bevel_width == 0) + resource.bevel_width = 3; - if (XrmGetResource(resource.stylerc, "rootCommand", "RootCommand", - &value_type, &value)) { - bexec(value.addr, displayString()); - } + if (! style.getValue("frameWidth", resource.frame_width) || + resource.frame_width > (getWidth() / 2)) + resource.frame_width = resource.bevel_width; - XrmDestroyDatabase(resource.stylerc); + if (style.getValue("rootCommand", s)) + bexec(s, displayString()); } @@ -741,6 +950,7 @@ BlackboxWindow *BScreen::getIcon(unsigned int index) { unsigned int BScreen::addWorkspace(void) { Workspace *wkspc = new Workspace(this, workspacesList.size()); workspacesList.push_back(wkspc); + saveWorkspaces(getWorkspaceCount()); workspacemenu->insert(wkspc->getName(), wkspc->getMenu(), wkspc->getID() + 2); @@ -771,6 +981,8 @@ unsigned int BScreen::removeLastWorkspace(void) { workspacesList.pop_back(); delete wkspc; + saveWorkspaces(getWorkspaceCount()); + toolbar->reconfigure(); updateNetizenWorkspaceCount(); @@ -783,19 +995,29 @@ void BScreen::changeWorkspaceID(unsigned int id) { if (! current_workspace) return; if (id != current_workspace->getID()) { + BlackboxWindow *focused = blackbox->getFocusedWindow(); + if (focused && focused->getScreen() == this && ! focused->isStuck()) { + if (focused->getWorkspaceNumber() != current_workspace->getID()) { + fprintf(stderr, "%s is on the wrong workspace, aborting\n", + focused->getTitle()); + abort(); + } + current_workspace->setLastFocusedWindow(focused); + } else { + // if no window had focus, no need to store a last focus + current_workspace->setLastFocusedWindow((BlackboxWindow *) 0); + } + // when we switch workspaces, unfocus whatever was focused + blackbox->setFocusedWindow((BlackboxWindow *) 0); + current_workspace->hideAll(); - workspacemenu->setItemSelected(current_workspace->getID() + 2, False); - if (blackbox->getFocusedWindow() && - blackbox->getFocusedWindow()->getScreen() == this && - (! blackbox->getFocusedWindow()->isStuck())) { - current_workspace->setLastFocusedWindow(blackbox->getFocusedWindow()); - blackbox->setFocusedWindow((BlackboxWindow *) 0); - } - current_workspace = getWorkspace(id); + xatom->setValue(getRootWindow(), XAtom::net_current_desktop, + XAtom::cardinal, id); + workspacemenu->setItemSelected(current_workspace->getID() + 2, True); toolbar->redrawWorkspaceLabel(True); @@ -811,18 +1033,128 @@ void BScreen::changeWorkspaceID(unsigned int id) { } +/* + * Set the _NET_CLIENT_LIST root window property. + */ +void BScreen::updateClientList(void) { + if (windowList.size() > 0) { + Window *windows = new Window[windowList.size()]; + Window *win_it = windows; + BlackboxWindowList::iterator it = windowList.begin(); + const BlackboxWindowList::iterator end = windowList.end(); + for (; it != end; ++it, ++win_it) + *win_it = (*it)->getClientWindow(); + xatom->setValue(getRootWindow(), XAtom::net_client_list, XAtom::window, + windows, windowList.size()); + delete [] windows; + } else + xatom->setValue(getRootWindow(), XAtom::net_client_list, XAtom::window, + 0, 0); +} + + +/* + * Set the _NET_CLIENT_LIST_STACKING root window property. + */ +void BScreen::updateStackingList(void) { + + BlackboxWindowList stack_order; + + /* + * Get the atacking order from all of the workspaces. + * We start with the current workspace so that the sticky windows will be + * in the right order on the current workspace. + * XXX: Do we need to have sticky windows in the list once for each workspace? + */ + getCurrentWorkspace()->appendStackOrder(stack_order); + for (unsigned int i = 0; i < getWorkspaceCount(); ++i) + if (i != getCurrentWorkspaceID()) + getWorkspace(i)->appendStackOrder(stack_order); + + if (stack_order.size() > 0) { + // set the client list atoms + Window *windows = new Window[stack_order.size()]; + Window *win_it = windows; + BlackboxWindowList::iterator it = stack_order.begin(); + const BlackboxWindowList::iterator end = stack_order.end(); + for (; it != end; ++it, ++win_it) + *win_it = (*it)->getClientWindow(); + xatom->setValue(getRootWindow(), XAtom::net_client_list_stacking, + XAtom::window, windows, stack_order.size()); + delete [] windows; + } else + xatom->setValue(getRootWindow(), XAtom::net_client_list_stacking, + XAtom::window, 0, 0); +} + + +void BScreen::addSystrayWindow(Window window) { + systrayWindowList.push_back(window); + xatom->setValue(getRootWindow(), XAtom::kde_net_system_tray_windows, + XAtom::window, + &systrayWindowList[0], systrayWindowList.size()); + blackbox->saveSystrayWindowSearch(window, this); +} + + +void BScreen::removeSystrayWindow(Window window) { + WindowList::iterator it = systrayWindowList.begin(); + const WindowList::iterator end = systrayWindowList.end(); + for (; it != end; ++it) + if (*it == window) { + systrayWindowList.erase(it); + xatom->setValue(getRootWindow(), XAtom::kde_net_system_tray_windows, + XAtom::window, + &systrayWindowList[0], systrayWindowList.size()); + blackbox->removeSystrayWindowSearch(window); + break; + } +} + + +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) { new BlackboxWindow(blackbox, w, this); BlackboxWindow *win = blackbox->searchWindow(w); if (! win) return; + if (win->isDesktop()) { + // 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(); XMapRequestEvent mre; mre.window = w; - win->restoreAttributes(); + if (blackbox->isStartup()) win->restoreAttributes(); win->mapRequestEvent(&mre); } @@ -837,12 +1169,20 @@ void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) { removeIcon(w); windowList.remove(w); + updateClientList(); if (blackbox->getFocusedWindow() == w) blackbox->setFocusedWindow((BlackboxWindow *) 0); removeNetizen(w->getClientWindow()); + /* + some managed windows can also be window group controllers. when + unmanaging such windows, we should also delete the window group. + */ + BWindowGroup *group = blackbox->searchGroup(w->getClientWindow()); + delete group; + delete w; } @@ -876,6 +1216,26 @@ void BScreen::removeNetizen(Window w) { } +void BScreen::updateWorkArea(void) { + if (workspacesList.size() > 0) { + unsigned long *dims = new unsigned long[4 * workspacesList.size()]; + for (unsigned int i = 0, m = workspacesList.size(); i < m; ++i) { + // XXX: this could be different for each workspace + const Rect &area = availableArea(); + dims[(i * 4) + 0] = area.x(); + dims[(i * 4) + 1] = area.y(); + dims[(i * 4) + 2] = area.width(); + dims[(i * 4) + 3] = area.height(); + } + xatom->setValue(getRootWindow(), XAtom::net_workarea, XAtom::cardinal, + dims, 4 * workspacesList.size()); + delete [] dims; + } else + xatom->setValue(getRootWindow(), XAtom::net_workarea, XAtom::cardinal, + 0, 0); +} + + void BScreen::updateNetizenCurrentWorkspace(void) { std::for_each(netizenList.begin(), netizenList.end(), std::mem_fun(&Netizen::sendCurrentWorkspace)); @@ -883,6 +1243,11 @@ void BScreen::updateNetizenCurrentWorkspace(void) { void BScreen::updateNetizenWorkspaceCount(void) { + xatom->setValue(getRootWindow(), XAtom::net_number_of_desktops, + XAtom::cardinal, workspacesList.size()); + + updateWorkArea(); + std::for_each(netizenList.begin(), netizenList.end(), std::mem_fun(&Netizen::sendWorkspaceCount)); } @@ -891,6 +1256,10 @@ void BScreen::updateNetizenWorkspaceCount(void) { void BScreen::updateNetizenWindowFocus(void) { Window f = ((blackbox->getFocusedWindow()) ? blackbox->getFocusedWindow()->getClientWindow() : None); + + xatom->setValue(getRootWindow(), XAtom::net_active_window, + XAtom::window, f); + NetizenList::iterator it = netizenList.begin(); for (; it != netizenList.end(); ++it) (*it)->sendWindowFocus(f); @@ -934,7 +1303,7 @@ void BScreen::updateNetizenConfigNotify(XEvent *e) { void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) { - // XXX: why 13?? + // the 13 represents the number of blackbox windows such as menus Window *session_stack = new Window[(num + workspacesList.size() + rootmenuList.size() + 13)]; unsigned int i = 0, k = num; @@ -978,33 +1347,18 @@ void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) { XRestackWindows(blackbox->getXDisplay(), session_stack, i); delete [] session_stack; -} - -#ifdef HAVE_STRFTIME -void BScreen::saveStrftimeFormat(const string& format) { - resource.strftime_format = format; + updateStackingList(); } -#endif // HAVE_STRFTIME -void BScreen::addWorkspaceName(const string& name) { - workspaceNames.push_back(name); -} - +void BScreen::lowerDesktops(void) { + if (desktopWindowList.empty()) return; -/* - * I would love to kill this function and the accompanying workspaceNames - * list. However, we have a chicken and egg situation. The names are read - * in during load_rc() which happens before the workspaces are created. - * The current solution is to read the names into a list, then use the list - * later for constructing the workspaces. It is only used during initial - * BScreen creation. - */ -const string BScreen::getNameOfWorkspace(unsigned int id) { - if (id < workspaceNames.size()) - return workspaceNames[id]; - return string(""); + XLowerWindow(blackbox->getXDisplay(), desktopWindowList[0]); + if (desktopWindowList.size() > 1) + XRestackWindows(blackbox->getXDisplay(), &desktopWindowList[0], + desktopWindowList.size()); } @@ -1060,7 +1414,7 @@ void BScreen::nextFocus(void) { do { current = next; next = current_workspace->getNextWindowInList(current); - } while(!next->setInputFocus() && next != focused); + } while(! next->setInputFocus() && next != focused); if (next != focused) current_workspace->raiseWindow(next); @@ -1089,7 +1443,7 @@ void BScreen::prevFocus(void) { do { current = next; next = current_workspace->getPrevWindowInList(current); - } while(!next->setInputFocus() && next != focused); + } while(! next->setInputFocus() && next != focused); if (next != focused) current_workspace->raiseWindow(next); @@ -1130,11 +1484,11 @@ void BScreen::InitMenu(void) { const char *menu_filename = blackbox->getMenuFilename(); if (menu_filename) - if (!(menu_file = fopen(menu_filename, "r"))) + if (! (menu_file = fopen(menu_filename, "r"))) perror(menu_filename); - if (!menu_file) { // opening the menu file failed, try the default menu + if (! menu_file) { // opening the menu file failed, try the default menu menu_filename = DEFAULTMENU; - if (!(menu_file = fopen(menu_filename, "r"))) + if (! (menu_file = fopen(menu_filename, "r"))) perror(menu_filename); } @@ -1176,7 +1530,7 @@ void BScreen::InitMenu(void) { rootmenu->setLabel(label); defaultMenu = parseMenuFile(menu_file, rootmenu); - if (!defaultMenu) + if (! defaultMenu) blackbox->addMenuTimestamp(menu_filename); break; } @@ -1553,19 +1907,10 @@ void BScreen::showPosition(int x, int y) { XClearWindow(blackbox->getXDisplay(), geom_window); - BPen pen(resource.wstyle.l_text_focus, resource.wstyle.font); - if (i18n.multibyte()) { - XmbDrawString(blackbox->getXDisplay(), geom_window, - resource.wstyle.fontset, pen.gc(), - resource.bevel_width, resource.bevel_width - - resource.wstyle.fontset_extents->max_ink_extent.y, - label, strlen(label)); - } else { - XDrawString(blackbox->getXDisplay(), geom_window, - pen.gc(), resource.bevel_width, - resource.wstyle.font->ascent + resource.bevel_width, - label, strlen(label)); - } + resource.wstyle.font->drawString(geom_window, + resource.bevel_width, resource.bevel_width, + resource.wstyle.l_text_focus, + label); } @@ -1587,19 +1932,10 @@ void BScreen::showGeometry(unsigned int gx, unsigned int gy) { XClearWindow(blackbox->getXDisplay(), geom_window); - BPen pen(resource.wstyle.l_text_focus, resource.wstyle.font); - if (i18n.multibyte()) { - XmbDrawString(blackbox->getXDisplay(), geom_window, - resource.wstyle.fontset, pen.gc(), - resource.bevel_width, resource.bevel_width - - resource.wstyle.fontset_extents->max_ink_extent.y, - label, strlen(label)); - } else { - XDrawString(blackbox->getXDisplay(), geom_window, - pen.gc(), resource.bevel_width, - resource.wstyle.font->ascent + - resource.bevel_width, label, strlen(label)); - } + resource.wstyle.font->drawString(geom_window, + resource.bevel_width, resource.bevel_width, + resource.wstyle.l_text_focus, + label); } @@ -1664,6 +2000,8 @@ void BScreen::updateAvailableArea(void) { for (; it != end; ++it) if ((*it)->isMaximized()) (*it)->remaximize(); } + + updateWorkArea(); } @@ -1673,7 +2011,7 @@ Workspace* BScreen::getWorkspace(unsigned int index) { } -void BScreen::buttonPressEvent(XButtonEvent *xbutton) { +void BScreen::buttonPressEvent(const XButtonEvent *xbutton) { if (xbutton->button == 1) { if (! isRootColormapInstalled()) image_control->installRootColormap(); @@ -1721,40 +2059,48 @@ void BScreen::buttonPressEvent(XButtonEvent *xbutton) { blackbox->checkMenu(); rootmenu->show(); } + // mouse wheel up + } else if (xbutton->button == 4) { + if (getCurrentWorkspaceID() >= getWorkspaceCount() - 1) + changeWorkspaceID(0); + else + changeWorkspaceID(getCurrentWorkspaceID() + 1); + // mouse wheel down + } else if (xbutton->button == 5) { + if (getCurrentWorkspaceID() == 0) + changeWorkspaceID(getWorkspaceCount() - 1); + else + changeWorkspaceID(getCurrentWorkspaceID() - 1); } } void BScreen::toggleFocusModel(FocusModel model) { + std::for_each(windowList.begin(), windowList.end(), + std::mem_fun(&BlackboxWindow::ungrabButtons)); + if (model == SloppyFocus) { saveSloppyFocus(True); } else { + // we're cheating here to save writing the config file 3 times + resource.auto_raise = False; + resource.click_raise = False; saveSloppyFocus(False); - saveAutoRaise(False); - saveClickRaise(False); } - updateFocusModel(); -} - - -void BScreen::updateFocusModel() -{ - std::for_each(workspacesList.begin(), workspacesList.end(), - std::mem_fun(&Workspace::updateFocusModel)); + std::for_each(windowList.begin(), windowList.end(), + std::mem_fun(&BlackboxWindow::grabButtons)); } BTexture BScreen::readDatabaseTexture(const string &rname, - const string &rclass, - const string &default_color) { + const string &default_color, + const Configuration &style) { BTexture texture; - XrmValue value; - char *value_type; + string s; - if (XrmGetResource(resource.stylerc, rname.c_str(), rclass.c_str(), - &value_type, &value)) - texture = BTexture(value.addr); + if (style.getValue(rname, s)) + texture = BTexture(s); else texture.setTexture(BTexture::Solid | BTexture::Flat); @@ -1764,233 +2110,43 @@ BTexture BScreen::readDatabaseTexture(const string &rname, if (texture.texture() & BTexture::Solid) { texture.setColor(readDatabaseColor(rname + ".color", - rclass + ".Color", - default_color)); + default_color, style)); texture.setColorTo(readDatabaseColor(rname + ".colorTo", - rclass + ".ColorTo", - default_color)); + default_color, style)); } else if (texture.texture() & BTexture::Gradient) { texture.setColor(readDatabaseColor(rname + ".color", - rclass + ".Color", - default_color)); + default_color, style)); texture.setColorTo(readDatabaseColor(rname + ".colorTo", - rclass + ".ColorTo", - default_color)); + default_color, style)); } return texture; } -BColor BScreen::readDatabaseColor(const string &rname, const string &rclass, - const string &default_color) { +BColor BScreen::readDatabaseColor(const string &rname, + const string &default_color, + const Configuration &style) { BColor color; - XrmValue value; - char *value_type; - if (XrmGetResource(resource.stylerc, rname.c_str(), rclass.c_str(), - &value_type, &value)) - color = BColor(value.addr, getBaseDisplay(), getScreenNumber()); + string s; + if (style.getValue(rname, s)) + color = BColor(s, getBaseDisplay(), getScreenNumber()); else color = BColor(default_color, getBaseDisplay(), getScreenNumber()); return color; } -XFontSet BScreen::readDatabaseFontSet(const string &rname, - const string &rclass) { - char *defaultFont = "fixed"; - - bool load_default = True; - XrmValue value; - char *value_type; - XFontSet fontset = 0; - if (XrmGetResource(resource.stylerc, rname.c_str(), rclass.c_str(), - &value_type, &value) && - (fontset = createFontSet(value.addr))) { - load_default = False; - } - - if (load_default) { - fontset = createFontSet(defaultFont); - - if (! fontset) { - fprintf(stderr, - i18n(ScreenSet, ScreenDefaultFontLoadFail, - "BScreen::setCurrentStyle(): couldn't load default font.\n")); - exit(2); - } - } - - return fontset; -} - - -XFontStruct *BScreen::readDatabaseFont(const string &rname, - const string &rclass) { - char *defaultFont = "fixed"; +BFont *BScreen::readDatabaseFont(const string &rname, + const Configuration &style) { + string fontname; - bool load_default = False; - XrmValue value; - char *value_type; - XFontStruct *font = 0; - if (XrmGetResource(resource.stylerc, rname.c_str(), rclass.c_str(), - &value_type, &value)) { - if ((font = XLoadQueryFont(blackbox->getXDisplay(), value.addr)) == NULL) { - fprintf(stderr, - i18n(ScreenSet, ScreenFontLoadFail, - "BScreen::setCurrentStyle(): couldn't load font '%s'\n"), - value.addr); - - load_default = True; - } - } else { - load_default = True; - } - - if (load_default) { - font = XLoadQueryFont(blackbox->getXDisplay(), defaultFont); - if (font == NULL) { - fprintf(stderr, - i18n(ScreenSet, ScreenDefaultFontLoadFail, - "BScreen::setCurrentStyle(): couldn't load default font.\n")); - exit(2); - } - } - - return font; -} - - -#ifndef HAVE_STRCASESTR -static const char * strcasestr(const char *str, const char *ptn) { - const char *s2, *p2; - for(; *str; str++) { - for(s2=str,p2=ptn; ; s2++,p2++) { - if (!*p2) return str; - if (toupper(*s2) != toupper(*p2)) break; - } - } - return NULL; -} -#endif // HAVE_STRCASESTR - - -static const char *getFontElement(const char *pattern, char *buf, - int bufsiz, ...) { - const char *p, *v; - char *p2; - va_list va; - - va_start(va, bufsiz); - buf[bufsiz-1] = 0; - buf[bufsiz-2] = '*'; - while((v = va_arg(va, char *)) != NULL) { - p = strcasestr(pattern, v); - if (p) { - strncpy(buf, p+1, bufsiz-2); - p2 = strchr(buf, '-'); - if (p2) *p2=0; - va_end(va); - return p; - } - } - va_end(va); - strncpy(buf, "*", bufsiz); - return NULL; -} - - -static const char *getFontSize(const char *pattern, int *size) { - const char *p; - const char *p2=NULL; - int n=0; - - for (p=pattern; 1; p++) { - if (!*p) { - if (p2!=NULL && n>1 && n<72) { - *size = n; return p2+1; - } else { - *size = 16; return NULL; - } - } else if (*p=='-') { - if (n>1 && n<72 && p2!=NULL) { - *size = n; - return p2+1; - } - p2=p; n=0; - } else if (*p>='0' && *p<='9' && p2!=NULL) { - n *= 10; - n += *p-'0'; - } else { - p2=NULL; n=0; - } - } -} - - -XFontSet BScreen::createFontSet(const string &fontname) { - XFontSet fs; - char **missing, *def = "-"; - int nmissing, pixel_size = 0, buf_size = 0; - char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE]; - - fs = XCreateFontSet(blackbox->getXDisplay(), - fontname.c_str(), &missing, &nmissing, &def); - if (fs && (! nmissing)) - return fs; - - const char *nfontname = fontname.c_str(); -#ifdef HAVE_SETLOCALE - if (! fs) { - if (nmissing) XFreeStringList(missing); - - setlocale(LC_CTYPE, "C"); - fs = XCreateFontSet(blackbox->getXDisplay(), fontname.c_str(), - &missing, &nmissing, &def); - setlocale(LC_CTYPE, ""); - } -#endif // HAVE_SETLOCALE - - if (fs) { - XFontStruct **fontstructs; - char **fontnames; - XFontsOfFontSet(fs, &fontstructs, &fontnames); - nfontname = fontnames[0]; - } + string s; + style.getValue(rname, s); // if this fails, a blank string will be used, + // which will cause the fallback font to load. - getFontElement(nfontname, weight, FONT_ELEMENT_SIZE, - "-medium-", "-bold-", "-demibold-", "-regular-", NULL); - getFontElement(nfontname, slant, FONT_ELEMENT_SIZE, - "-r-", "-i-", "-o-", "-ri-", "-ro-", NULL); - getFontSize(nfontname, &pixel_size); - - if (! strcmp(weight, "*")) - strncpy(weight, "medium", FONT_ELEMENT_SIZE); - if (! strcmp(slant, "*")) - strncpy(slant, "r", FONT_ELEMENT_SIZE); - if (pixel_size < 3) - pixel_size = 3; - else if (pixel_size > 97) - pixel_size = 97; - - buf_size = strlen(nfontname) + (FONT_ELEMENT_SIZE * 2) + 64; - char *pattern2 = new char[buf_size]; - sprintf(pattern2, - "%s," - "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*," - "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*", - nfontname, weight, slant, pixel_size, pixel_size); - nfontname = pattern2; - - if (nmissing) - XFreeStringList(missing); - if (fs) - XFreeFontSet(blackbox->getXDisplay(), fs); - - fs = XCreateFontSet(blackbox->getXDisplay(), nfontname, &missing, - &nmissing, &def); - - delete [] pattern2; - - return fs; + BFont *b = new BFont(blackbox->getXDisplay(), this, s); + if (! b->valid()) + exit(2); // can't continue without a font + return b; }