From 73f6bb1a7b6bb5f8b9cf22587722d713a1f15b59 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sun, 10 Nov 2002 10:22:47 +0000 Subject: move screen.cc/hh to bbscreen.cc/hh --- src/Makefile.am | 2 +- src/bbscreen.cc | 1555 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/bbscreen.hh | 268 +++++++++ src/bbwindow.cc | 2 +- src/blackbox.cc | 2 +- src/client.cc | 2 +- src/frame.hh | 4 +- src/screen.cc | 1555 -------------------------------------------------- src/screen.hh | 268 --------- src/workspace.cc | 2 +- src/xeventhandler.cc | 2 +- 11 files changed, 1831 insertions(+), 1831 deletions(-) create mode 100644 src/bbscreen.cc create mode 100644 src/bbscreen.hh delete mode 100644 src/screen.cc delete mode 100644 src/screen.hh (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index cbbebb23..ef61e4c7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,7 +15,7 @@ bin_PROGRAMS= openbox3 openbox3_LDADD=../otk/libotk.a @LIBINTL@ -openbox3_SOURCES= client.cc frame.cc screen.cc openbox.cc \ +openbox3_SOURCES= client.cc frame.cc bbscreen.cc openbox.cc \ bbwindow.cc workspace.cc blackbox.cc \ main.cc xeventhandler.cc diff --git a/src/bbscreen.cc b/src/bbscreen.cc new file mode 100644 index 00000000..ebfceb98 --- /dev/null +++ b/src/bbscreen.cc @@ -0,0 +1,1555 @@ +// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- + +#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 + +#ifdef HAVE_STRING_H +# include +#endif // HAVE_STRING_H + +#ifdef HAVE_CTYPE_H +# include +#endif // HAVE_CTYPE_H + +#ifdef HAVE_UNISTD_H +# include +# include +#endif // HAVE_UNISTD_H + +#ifdef HAVE_DIRENT_H +# include +#endif // HAVE_DIRENT_H + +#ifdef HAVE_LOCALE_H +# include +#endif // HAVE_LOCALE_H + +#ifdef HAVE_SYS_STAT_H +# include +#endif // HAVE_SYS_STAT_H + +#ifdef HAVE_STDARG_H +# include +#endif // HAVE_STDARG_H +} + +#include + +#include +#include +#include +using std::string; + +#include "bbscreen.hh" +#include "otk/font.hh" +#include "otk/gccache.hh" +#include "otk/image.hh" +#include "otk/assassin.hh" +#include "otk/util.hh" +#include "openbox.hh" +#include "bbwindow.hh" +#include "workspace.hh" + +#ifndef FONT_ELEMENT_SIZE +#define FONT_ELEMENT_SIZE 50 +#endif // FONT_ELEMENT_SIZE + +namespace ob { + +static bool running = True; + +static int anotherWMRunning(Display *display, XErrorEvent *) { + fprintf(stderr, + "BScreen::BScreen: an error occured while querying the X server.\n" + " another window manager already running on display %s.\n", + DisplayString(display)); + + running = False; + + return(-1); +} + + +BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(scrn) { + blackbox = bb; + screenstr = "session.screen" + otk::itostring(scrn) + '.'; + config = blackbox->getConfig(); + xatom = blackbox->getXAtom(); + + event_mask = ColormapChangeMask | EnterWindowMask | PropertyChangeMask | + SubstructureRedirectMask | ButtonPressMask | ButtonReleaseMask; + + XErrorHandler old = XSetErrorHandler((XErrorHandler) anotherWMRunning); + XSelectInput(otk::OBDisplay::display, getRootWindow(), event_mask); + XSync(otk::OBDisplay::display, False); + XSetErrorHandler((XErrorHandler) old); + + managed = running; + if (! managed) return; + + fprintf(stderr, "BScreen::BScreen: managing screen %d " + "using visual 0x%lx, depth %d\n", + getScreenNumber(), XVisualIDFromVisual(getVisual()), + getDepth()); + + resource.wstyle.font = (otk::BFont *) 0; + + geom_pixmap = None; + +// xatom->setSupported(this); // set-up netwm support +#ifdef HAVE_GETPID + xatom->setValue(getRootWindow(), otk::OBProperty::blackbox_pid, + otk::OBProperty::Atom_Cardinal, + (unsigned long) getpid()); +#endif // HAVE_GETPID + unsigned long geometry[] = { getWidth(), + getHeight()}; + xatom->set(getRootWindow(), otk::OBProperty::net_desktop_geometry, + otk::OBProperty::Atom_Cardinal, geometry, 2); + unsigned long viewport[] = {0,0}; + xatom->set(getRootWindow(), otk::OBProperty::net_desktop_viewport, + otk::OBProperty::Atom_Cardinal, viewport, 2); + + + XDefineCursor(otk::OBDisplay::display, getRootWindow(), + blackbox->getSessionCursor()); + + updateAvailableArea(); + + image_control = + new otk::BImageControl(Openbox::instance->timerManager(), + this, True, blackbox->getColorsPerChannel(), + blackbox->getCacheLife(), blackbox->getCacheMax()); + image_control->installRootColormap(); + root_colormap_installed = True; + + load_rc(); + + // XXX: ugh + resource.wstyle.setImageControl(image_control); + resource.wstyle.setScreenNumber(scrn); + LoadStyle(); + + XGCValues gcv; + gcv.foreground = WhitePixel(otk::OBDisplay::display, getScreenNumber()) + ^ BlackPixel(otk::OBDisplay::display, getScreenNumber()); + gcv.function = GXxor; + gcv.subwindow_mode = IncludeInferiors; + opGC = XCreateGC(otk::OBDisplay::display, getRootWindow(), + GCForeground | GCFunction | GCSubwindowMode, &gcv); + + const char *s = "0: 0000 x 0: 0000"; + geom_w = resource.wstyle.font->measureString(s) + resource.wstyle.bevel_width * 2; + geom_h = resource.wstyle.font->height() + resource.wstyle.bevel_width * 2; + + XSetWindowAttributes attrib; + unsigned long mask = CWBorderPixel | CWColormap | CWSaveUnder; + attrib.border_pixel = getBorderColor()->pixel(); + attrib.colormap = getColormap(); + attrib.save_under = True; + + // XXX -- move this geom_* crap out of here + + geom_window = XCreateWindow(otk::OBDisplay::display, getRootWindow(), + 0, 0, geom_w, geom_h, resource.wstyle.border_width, + getDepth(), InputOutput, getVisual(), + mask, &attrib); + geom_visible = False; + + otk::BTexture* texture = &(resource.wstyle.l_focus); + geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap); + if (geom_pixmap == ParentRelative) { + texture = &(resource.wstyle.t_focus); + geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap); + } + if (! geom_pixmap) + XSetWindowBackground(otk::OBDisplay::display, geom_window, + texture->color().pixel()); + else + XSetWindowBackgroundPixmap(otk::OBDisplay::display, + geom_window, geom_pixmap); + + if (resource.workspaces > 0) { + for (unsigned int i = 0; i < resource.workspaces; ++i) { + Workspace *wkspc = new Workspace(this, workspacesList.size()); + workspacesList.push_back(wkspc); + + } + } else { + Workspace *wkspc = new Workspace(this, workspacesList.size()); + workspacesList.push_back(wkspc); + } + + // /GEOM_PIXMAP + + saveWorkspaceNames(); + + updateNetizenWorkspaceCount(); + + current_workspace = workspacesList.front(); + + xatom->set(getRootWindow(), otk::OBProperty::net_current_desktop, + otk::OBProperty::Atom_Cardinal, 0); //first workspace + + raiseWindows(0, 0); // this also initializes the empty stacking list + + updateClientList(); // initialize the client lists, which will be empty + updateAvailableArea(); + + changeWorkspaceID(0); + + unsigned int i, j, nchild; + Window r, p, *children; + XQueryTree(otk::OBDisplay::display, getRootWindow(), &r, &p, + &children, &nchild); + + // preen the window list of all icon windows... for better dockapp support + for (i = 0; i < nchild; i++) { + if (children[i] == None) continue; + + XWMHints *wmhints = XGetWMHints(otk::OBDisplay::display, + children[i]); + + if (wmhints) { + if ((wmhints->flags & IconWindowHint) && + (wmhints->icon_window != children[i])) { + for (j = 0; j < nchild; j++) { + if (children[j] == wmhints->icon_window) { + children[j] = None; + break; + } + } + } + + XFree(wmhints); + } + } + + // manage shown windows + for (i = 0; i < nchild; ++i) { + if (children[i] == None || ! blackbox->validateWindow(children[i])) + continue; + + XWindowAttributes attrib; + if (XGetWindowAttributes(otk::OBDisplay::display, children[i], &attrib)) { + if (attrib.override_redirect) continue; + + if (attrib.map_state != IsUnmapped) { + manageWindow(children[i]); + } + } + } + + XFree(children); + + // call this again just in case a window we found updates the Strut list + updateAvailableArea(); +} + + +BScreen::~BScreen(void) { + if (! managed) return; + + if (geom_pixmap != None) + image_control->removeImage(geom_pixmap); + + if (geom_window != None) + XDestroyWindow(otk::OBDisplay::display, geom_window); + + std::for_each(workspacesList.begin(), workspacesList.end(), + otk::PointerAssassin()); + + std::for_each(iconList.begin(), iconList.end(), otk::PointerAssassin()); + + while (! systrayWindowList.empty()) + removeSystrayWindow(systrayWindowList[0]); + + delete image_control; + + // delete style + + XFreeGC(otk::OBDisplay::display, opGC); +} + + +void BScreen::LoadStyle(void) { + otk::Configuration style_conf(False); + + const char *sfile = blackbox->getStyleFilename(); + if (sfile != NULL) { + style_conf.setFile(sfile); + if (! style_conf.load()) { + style_conf.setFile(DEFAULTSTYLE); + if (! style_conf.load()) + style_conf.create(); // hardcoded default values will be used. + } + } + + // merge in the rc file + style_conf.merge(config->file(), True); + + resource.wstyle.load(style_conf); +} + +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::saveAAFonts(bool f) { + resource.aa_fonts = f; + config->setValue(screenstr + "antialiasFonts", resource.aa_fonts); + reconfigure(); +} + + +void BScreen::saveShadowFonts(bool f) { + resource.shadow_fonts = f; + config->setValue(screenstr + "dropShadowFonts", resource.shadow_fonts); + reconfigure(); +} + + +void BScreen::saveWindowToEdgeSnap(int s) { + resource.snap_to_edges = s; + + const char *snap; + switch (resource.snap_to_edges) { + case WindowNoSnap: snap = "NoSnap"; break; + case WindowResistance: snap = "Resistance"; break; + case WindowSnap: default: snap = "Snap"; break; + } + config->setValue(screenstr + "windowToEdgeSnap", snap); +} + + +void BScreen::saveWindowToWindowSnap(int s) { + resource.snap_to_windows = s; + + const char *snap; + switch (resource.snap_to_windows) { + case WindowNoSnap: snap = "NoSnap"; break; + case WindowResistance: snap = "Resistance"; break; + case WindowSnap: default: snap = "Snap"; break; + } + config->setValue(screenstr + "windowToWindowSnap", snap); +} + + +void BScreen::saveResizeZones(unsigned int z) { + resource.resize_zones = z; + config->setValue(screenstr + "resizeZones", resource.resize_zones); +} + + +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 UnderMousePlacement: placement = "UnderMousePlacement"; break; + case ClickMousePlacement: placement = "ClickMousePlacement"; break; + case ColSmartPlacement: placement = "ColSmartPlacement"; break; + case RowSmartPlacement: default: placement = "RowSmartPlacement"; break; + } + config->setValue(screenstr + "windowPlacement", placement); +} + + +void BScreen::saveResistanceSize(int s) { + resource.resistance_size = s; + config->setValue(screenstr + "resistanceSize", + resource.resistance_size); +} + + +void BScreen::saveSnapThreshold(int t) { + resource.snap_threshold = t; + config->setValue(screenstr + "edgeSnapThreshold", + resource.snap_threshold); +} + + +void BScreen::saveSnapOffset(int t) { + resource.snap_offset = t; + config->setValue(screenstr + "edgeSnapOffset", + resource.snap_offset); +} + + +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"); +} + + +void BScreen::saveStrftimeFormat(const std::string& format) { + resource.strftime_format = format; + config->setValue(screenstr + "strftimeFormat", resource.strftime_format); +} + + +void BScreen::saveWorkspaceNames() { + string names; + + for (unsigned int i = 0; i < workspacesList.size(); ++i) { + names += workspacesList[i]->getName(); + if (i < workspacesList.size() - 1) + names += ','; + } + + config->setValue(screenstr + "workspaceNames", names); +} + + +void BScreen::savePlaceIgnoreShaded(bool i) { + resource.ignore_shaded = i; + config->setValue(screenstr + "placementIgnoreShaded", + resource.ignore_shaded); +} + + +void BScreen::savePlaceIgnoreMaximized(bool i) { + resource.ignore_maximized = i; + config->setValue(screenstr + "placementIgnoreMaximized", + resource.ignore_maximized); +} + + +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::saveRootScrollDirection(int d) { + resource.root_scroll = d; + const char *dir; + switch (resource.root_scroll) { + case NoScroll: dir = "None"; break; + case ReverseScroll: dir = "Reverse"; break; + case NormalScroll: default: dir = "Normal"; break; + } + config->setValue(screenstr + "rootScrollDirection", dir); +} + + +void BScreen::save_rc(void) { + saveSloppyFocus(resource.sloppy_focus); + saveAutoRaise(resource.auto_raise); + saveImageDither(doImageDither()); + saveShadowFonts(resource.shadow_fonts); + saveAAFonts(resource.aa_fonts); + saveResizeZones(resource.resize_zones); + saveOpaqueMove(resource.opaque_move); + saveFullMax(resource.full_max); + saveFocusNew(resource.focus_new); + saveFocusLast(resource.focus_last); + saveWindowToWindowSnap(resource.snap_to_windows); + saveWindowToEdgeSnap(resource.snap_to_edges); + saveWindowCornerSnap(resource.window_corner_snap); + saveWorkspaces(resource.workspaces); + savePlacementPolicy(resource.placement_policy); + saveSnapThreshold(resource.snap_threshold); + saveSnapOffset(resource.snap_offset); + saveResistanceSize(resource.resistance_size); + saveRowPlacementDirection(resource.row_direction); + saveColPlacementDirection(resource.col_direction); + saveStrftimeFormat(resource.strftime_format); + savePlaceIgnoreShaded(resource.ignore_shaded); + savePlaceIgnoreMaximized(resource.ignore_maximized); + saveAllowScrollLock(resource.allow_scroll_lock); + saveWorkspaceWarping(resource.workspace_warping); + saveRootScrollDirection(resource.root_scroll); +} + + +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 + "antialiasFonts", resource.aa_fonts)) + resource.aa_fonts = true; + + if (! resource.aa_fonts || + ! config->getValue(screenstr + "dropShadowFonts", resource.shadow_fonts)) + resource.shadow_fonts = false; + + if (! config->getValue(screenstr + "resizeZones", resource.resize_zones) || + (resource.resize_zones != 1 && resource.resize_zones != 2 && + resource.resize_zones != 4)) + resource.resize_zones = 4; + + resource.snap_to_windows = WindowResistance; + if (config->getValue(screenstr + "windowToWindowSnap", s)) { + if (s == "NoSnap") + resource.snap_to_windows = WindowNoSnap; + else if (s == "Snap") + resource.snap_to_windows = WindowSnap; + } + + resource.snap_to_edges = WindowResistance; + if (config->getValue(screenstr + "windowToEdgeSnap", s)) { + if (s == "NoSnap") + resource.snap_to_edges = WindowNoSnap; + else if (s == "Snap") + resource.snap_to_edges = WindowSnap; + } + + 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 + "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)) + resource.snap_threshold = 4; + + if (! config->getValue(screenstr + "resistanceSize", + resource.resistance_size)) + resource.resistance_size = 18; + + 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; + + if (config->getValue(screenstr + "workspaceNames", s)) { + otk::OBProperty::StringVect workspaceNames; + + 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->set(getRootWindow(), otk::OBProperty::net_desktop_names, + otk::OBProperty::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 == "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") + resource.placement_policy = RowSmartPlacement; + } else + resource.placement_policy = RowSmartPlacement; + + if (! config->getValue(screenstr + "strftimeFormat", + resource.strftime_format)) + resource.strftime_format = "%I:%M %p"; + + if (! config->getValue(screenstr + "placementIgnoreShaded", + resource.ignore_shaded)) + resource.ignore_shaded = true; + + 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; + + resource.root_scroll = NormalScroll; + if (config->getValue(screenstr + "rootScrollDirection", s)) { + if (s == "None") + resource.root_scroll = NoScroll; + else if (s == "Reverse") + resource.root_scroll = ReverseScroll; + } +} + + +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->state() == Openbox::State_Starting) return; + + 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(otk::OBDisplay::display, + getScreenNumber()); + gcv.function = GXinvert; + gcv.subwindow_mode = IncludeInferiors; + XChangeGC(otk::OBDisplay::display, opGC, + GCForeground | GCFunction | GCSubwindowMode, &gcv); + + const char *s = "0: 0000 x 0: 0000"; + + geom_w = resource.wstyle.font->measureString(s) + resource.wstyle.bevel_width * 2; + geom_h = resource.wstyle.font->height() + resource.wstyle.bevel_width * 2; + + otk::BTexture* texture = &(resource.wstyle.l_focus); + geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap); + if (geom_pixmap == ParentRelative) { + texture = &(resource.wstyle.t_focus); + geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap); + } + if (! geom_pixmap) + XSetWindowBackground(otk::OBDisplay::display, geom_window, + texture->color().pixel()); + else + XSetWindowBackgroundPixmap(otk::OBDisplay::display, + geom_window, geom_pixmap); + + XSetWindowBorderWidth(otk::OBDisplay::display, geom_window, + resource.wstyle.border_width); + XSetWindowBorder(otk::OBDisplay::display, geom_window, + resource.wstyle.border_color.pixel()); + + typedef std::vector SubList; + SubList remember_subs; + + raiseWindows(0, 0); + + std::for_each(workspacesList.begin(), workspacesList.end(), + std::mem_fun(&Workspace::reconfigure)); + + BlackboxWindowList::iterator iit = iconList.begin(); + for (; iit != iconList.end(); ++iit) { + BlackboxWindow *bw = *iit; + if (bw->validateClient()) + bw->reconfigure(); + } + + otk::BImageControl::timeout(image_control); +} + + + +void BScreen::addIcon(BlackboxWindow *w) { + if (! w) return; + + w->setWorkspace(otk::BSENTINEL); + w->setWindowNumber(iconList.size()); + + iconList.push_back(w); +} + + +void BScreen::removeIcon(BlackboxWindow *w) { + if (! w) return; + + iconList.remove(w); + + BlackboxWindowList::iterator it = iconList.begin(), + end = iconList.end(); + for (int i = 0; it != end; ++it) + (*it)->setWindowNumber(i++); +} + + +BlackboxWindow *BScreen::getIcon(unsigned int index) { + if (index < iconList.size()) { + BlackboxWindowList::iterator it = iconList.begin(); + while (index-- > 0) // increment to index + ++it; + return *it; + } + + return (BlackboxWindow *) 0; +} + + +unsigned int BScreen::addWorkspace(void) { + Workspace *wkspc = new Workspace(this, workspacesList.size()); + workspacesList.push_back(wkspc); + saveWorkspaces(getWorkspaceCount()); + saveWorkspaceNames(); + + return workspacesList.size(); +} + + +unsigned int BScreen::removeLastWorkspace(void) { + if (workspacesList.size() == 1) + return 1; + + Workspace *wkspc = workspacesList.back(); + + if (current_workspace->getID() == wkspc->getID()) + changeWorkspaceID(current_workspace->getID() - 1); + + wkspc->removeAll(); + + workspacesList.pop_back(); + delete wkspc; + + saveWorkspaces(getWorkspaceCount()); + saveWorkspaceNames(); + + updateNetizenWorkspaceCount(); + + return workspacesList.size(); +} + + +void BScreen::changeWorkspaceID(unsigned int id) { + if (! current_workspace || id == current_workspace->getID()) return; + + BlackboxWindow *focused = blackbox->getFocusedWindow(); + if (focused && focused->getScreen() == this) { + assert(focused->isStuck() || + focused->getWorkspaceNumber() == current_workspace->getID()); + + 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 if it is going + // to be unmapped + if (focused && ! focused->isStuck()) + blackbox->setFocusedWindow((BlackboxWindow *) 0); + + current_workspace->hideAll(); + + current_workspace = getWorkspace(id); + + xatom->set(getRootWindow(), otk::OBProperty::net_current_desktop, + otk::OBProperty::Atom_Cardinal, id); + + current_workspace->showAll(); + + int x, y, rx, ry; + Window c, r; + unsigned int m; + BlackboxWindow *win = (BlackboxWindow *) 0; + bool f = False; + + XSync(otk::OBDisplay::display, False); + + // If sloppy focus and we can find the client window under the pointer, + // try to focus it. + if (resource.sloppy_focus && + XQueryPointer(otk::OBDisplay::display, 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); +} + + +/* + * 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->set(getRootWindow(), otk::OBProperty::net_client_list, + otk::OBProperty::Atom_Window, windows, windowList.size()); + delete [] windows; + } else + xatom->set(getRootWindow(), otk::OBProperty::net_client_list, + otk::OBProperty::Atom_Window, 0, 0); + + updateStackingList(); +} + + +/* + * Set the _NET_CLIENT_LIST_STACKING root window property. + */ +void BScreen::updateStackingList(void) { + + BlackboxWindowList stack_order; + + /* + * Get the stacking 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(), + end = stack_order.end(); + for (; it != end; ++it, ++win_it) + *win_it = (*it)->getClientWindow(); + xatom->set(getRootWindow(), otk::OBProperty::net_client_list_stacking, + otk::OBProperty::Atom_Window, windows, stack_order.size()); + delete [] windows; + } else + xatom->set(getRootWindow(), otk::OBProperty::net_client_list_stacking, + otk::OBProperty::Atom_Window, 0, 0); +} + + +void BScreen::addSystrayWindow(Window window) { + XGrabServer(otk::OBDisplay::display); + + XSelectInput(otk::OBDisplay::display, window, StructureNotifyMask); + systrayWindowList.push_back(window); + xatom->set(getRootWindow(), otk::OBProperty::kde_net_system_tray_windows, + otk::OBProperty::Atom_Window, + &systrayWindowList[0], systrayWindowList.size()); + blackbox->saveSystrayWindowSearch(window, this); + + XUngrabServer(otk::OBDisplay::display); +} + + +void BScreen::removeSystrayWindow(Window window) { + XGrabServer(otk::OBDisplay::display); + + WindowList::iterator it = systrayWindowList.begin(); + const WindowList::iterator end = systrayWindowList.end(); + for (; it != end; ++it) + if (*it == window) { + systrayWindowList.erase(it); + xatom->set(getRootWindow(), + otk::OBProperty::kde_net_system_tray_windows, + otk::OBProperty::Atom_Window, + &systrayWindowList[0], systrayWindowList.size()); + blackbox->removeSystrayWindowSearch(window); + XSelectInput(otk::OBDisplay::display, window, NoEventMask); + break; + } + + assert(it != end); // not a systray window + + XUngrabServer(otk::OBDisplay::display); +} + + +void BScreen::manageWindow(Window w) { + // is the window a KDE systray window? + Window systray; + if (xatom->get(w, otk::OBProperty::kde_net_wm_system_tray_window_for, + otk::OBProperty::Atom_Window, &systray) && + systray != None) + { + addSystrayWindow(w); + return; + } + + // is the window a docking app + XWMHints *wmhint = XGetWMHints(otk::OBDisplay::display, w); + if (wmhint && (wmhint->flags & StateHint) && + wmhint->initial_state == WithdrawnState) { + //slit->addClient(w); + return; + } + + new BlackboxWindow(blackbox, w, this); + + BlackboxWindow *win = blackbox->searchWindow(w); + if (! win) + return; + + 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(); + + if (win->isTopmost()) + specialWindowList.push_back(win->getFrameWindow()); + } + + XMapRequestEvent mre; + mre.window = w; + if (blackbox->state() == Openbox::State_Starting && + win->isNormal()) + win->restoreAttributes(); + win->mapRequestEvent(&mre); +} + + +void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) { + // is the window a KDE systray window? + Window systray; + if (xatom->get(w->getClientWindow(), + otk::OBProperty::kde_net_wm_system_tray_window_for, + otk::OBProperty::Atom_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 + if (w->isModal()) w->setModal(False); + + if (w->getWorkspaceNumber() != otk::BSENTINEL && + w->getWindowNumber() != otk::BSENTINEL) { + getWorkspace(w->getWorkspaceNumber())->removeWindow(w); + if (w->isStuck()) { + for (unsigned int i = 0; i < getNumberOfWorkspaces(); ++i) + if (i != w->getWorkspaceNumber()) + getWorkspace(i)->removeWindow(w, True); + } + } else if (w->isIconic()) + removeIcon(w); + + 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? + } 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) + blackbox->setFocusedWindow((BlackboxWindow *) 0); + + /* + 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; +} + + +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 otk::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->set(getRootWindow(), otk::OBProperty::net_workarea, + otk::OBProperty::Atom_Cardinal, + dims, 4 * workspacesList.size()); + delete [] dims; + } else + xatom->set(getRootWindow(), otk::OBProperty::net_workarea, + otk::OBProperty::Atom_Cardinal, 0, 0); +} + + +void BScreen::updateNetizenWorkspaceCount(void) { + xatom->set(getRootWindow(), otk::OBProperty::net_number_of_desktops, + otk::OBProperty::Atom_Cardinal, workspacesList.size()); + + updateWorkArea(); +} + + +void BScreen::updateNetizenWindowFocus(void) { + Window f = ((blackbox->getFocusedWindow()) ? + blackbox->getFocusedWindow()->getClientWindow() : None); + + xatom->set(getRootWindow(), otk::OBProperty::net_active_window, + otk::OBProperty::Atom_Window, f); +} + + +void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) { + // the 13 represents the number of blackbox windows such as menus + int bbwins = 15; +#ifdef XINERAMA + ++bbwins; +#endif // XINERAMA + + Window *session_stack = new + Window[(num + specialWindowList.size() + bbwins)]; + unsigned int i = 0, k = num; + + 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); + + XRestackWindows(otk::OBDisplay::display, session_stack, i); + + delete [] session_stack; + + updateStackingList(); +} + + +void BScreen::lowerWindows(Window *workspace_stack, unsigned int num) { + assert(num > 0); // this would cause trouble in the XRaiseWindow call + + Window *session_stack = new Window[(num + desktopWindowList.size())]; + unsigned int i = 0, k = num; + + XLowerWindow(otk::OBDisplay::display, workspace_stack[0]); + + while (k--) + *(session_stack + i++) = *(workspace_stack + k); + + WindowList::iterator dit = desktopWindowList.begin(); + const WindowList::iterator d_end = desktopWindowList.end(); + for (; dit != d_end; ++dit) + *(session_stack + i++) = *dit; + + XRestackWindows(otk::OBDisplay::display, session_stack, i); + + delete [] session_stack; + + updateStackingList(); +} + + +void BScreen::reassociateWindow(BlackboxWindow *w, unsigned int wkspc_id, + bool ignore_sticky) { + if (! w) return; + + if (wkspc_id == otk::BSENTINEL) + wkspc_id = current_workspace->getID(); + + if (w->getWorkspaceNumber() == wkspc_id) + return; + + if (w->isIconic()) { + removeIcon(w); + getWorkspace(wkspc_id)->addWindow(w); + if (w->isStuck()) + for (unsigned int i = 0; i < getNumberOfWorkspaces(); ++i) + if (i != w->getWorkspaceNumber()) + getWorkspace(i)->addWindow(w, True); + } else if (ignore_sticky || ! w->isStuck()) { + if (w->isStuck()) + w->stick(); + getWorkspace(w->getWorkspaceNumber())->removeWindow(w); + getWorkspace(wkspc_id)->addWindow(w); + } + updateStackingList(); +} + + +void BScreen::propagateWindowName(const BlackboxWindow *bw) { + if (bw->isIconic()) { + } else { + } +} + + +void BScreen::nextFocus(void) const { + BlackboxWindow *focused = blackbox->getFocusedWindow(), + *next = focused; + + if (focused && + focused->getScreen()->getScreenNumber() == getScreenNumber() && + current_workspace->getCount() > 1) { + do { + next = current_workspace->getNextWindowInList(next); + } while (next != focused && ! next->setInputFocus()); + + if (next != focused) + current_workspace->raiseWindow(next); + } else if (current_workspace->getCount() > 0) { + next = current_workspace->getTopWindowOnStack(); + next->setInputFocus(); + current_workspace->raiseWindow(next); + } +} + + +void BScreen::prevFocus(void) const { + BlackboxWindow *focused = blackbox->getFocusedWindow(), + *next = focused; + + if (focused) { + // if window is not on this screen, ignore it + if (focused->getScreen()->getScreenNumber() != getScreenNumber()) + focused = (BlackboxWindow*) 0; + } + + if (focused && + focused->getScreen()->getScreenNumber() == getScreenNumber() && + current_workspace->getCount() > 1) { + // next is the next window to receive focus, current is a place holder + do { + next = current_workspace->getPrevWindowInList(next); + } while (next != focused && ! next->setInputFocus()); + + if (next != focused) + current_workspace->raiseWindow(next); + } else if (current_workspace->getCount() > 0) { + next = current_workspace->getTopWindowOnStack(); + next->setInputFocus(); + current_workspace->raiseWindow(next); + } +} + + +void BScreen::raiseFocus(void) const { + BlackboxWindow *focused = blackbox->getFocusedWindow(); + if (! focused) + return; + + // if on this Screen, raise it + if (focused->getScreen()->getScreenNumber() == getScreenNumber()) { + Workspace *workspace = getWorkspace(focused->getWorkspaceNumber()); + workspace->raiseWindow(focused); + } +} + + +void BScreen::shutdown(void) { + XSelectInput(otk::OBDisplay::display, getRootWindow(), NoEventMask); + XSync(otk::OBDisplay::display, False); + + while(! windowList.empty()) + unmanageWindow(windowList.front(), True); + + while(! desktopWindowList.empty()) { + BlackboxWindow *win = blackbox->searchWindow(desktopWindowList.front()); + assert(win); + unmanageWindow(win, True); + } +} + + +void BScreen::showPosition(int x, int y) { + if (! geom_visible) { + XMoveResizeWindow(otk::OBDisplay::display, geom_window, + (getWidth() - geom_w) / 2, + (getHeight() - geom_h) / 2, geom_w, geom_h); + XMapWindow(otk::OBDisplay::display, geom_window); + XRaiseWindow(otk::OBDisplay::display, geom_window); + + geom_visible = True; + } + + char label[1024]; + + sprintf(label, "X: %4d x Y: %4d", x, y); + + XClearWindow(otk::OBDisplay::display, geom_window); + + resource.wstyle.font->drawString(geom_window, + resource.wstyle.bevel_width, resource.wstyle.bevel_width, + resource.wstyle.l_text_focus, + label); +} + + +void BScreen::showGeometry(unsigned int gx, unsigned int gy) { + if (! geom_visible) { + XMoveResizeWindow(otk::OBDisplay::display, geom_window, + (getWidth() - geom_w) / 2, + (getHeight() - geom_h) / 2, geom_w, geom_h); + XMapWindow(otk::OBDisplay::display, geom_window); + XRaiseWindow(otk::OBDisplay::display, geom_window); + + geom_visible = True; + } + + char label[1024]; + + sprintf(label, "W: %4d x H: %4d", gx, gy); + + XClearWindow(otk::OBDisplay::display, geom_window); + + resource.wstyle.font->drawString(geom_window, + resource.wstyle.bevel_width, resource.wstyle.bevel_width, + resource.wstyle.l_text_focus, + label); +} + + +void BScreen::hideGeometry(void) { + if (geom_visible) { + XUnmapWindow(otk::OBDisplay::display, geom_window); + geom_visible = False; + } +} + + +void BScreen::addStrut(otk::Strut *strut) { + strutList.push_back(strut); +} + + +void BScreen::removeStrut(otk::Strut *strut) { + strutList.remove(strut); +} + + +const otk::Rect& BScreen::availableArea(void) const { + if (doFullMax()) + return getRect(); // return the full screen + return usableArea; +} + + +#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) { + otk::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 + * do not be confused by the similarity to the names of Rect's members + */ + unsigned int current_left = 0, current_right = 0, current_top = 0, + current_bottom = 0; + + StrutList::const_iterator it = strutList.begin(), end = strutList.end(); + + for(; it != end; ++it) { + otk::Strut *strut = *it; + if (strut->left > current_left) + current_left = strut->left; + if (strut->top > current_top) + current_top = strut->top; + if (strut->right > current_right) + current_right = strut->right; + if (strut->bottom > current_bottom) + current_bottom = strut->bottom; + } + + usableArea.setPos(current_left, current_top); + 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(); + for (; it != end; ++it) + if ((*it)->isMaximized()) (*it)->remaximize(); + } + + updateWorkArea(); +} + + +Workspace* BScreen::getWorkspace(unsigned int index) const { + assert(index < workspacesList.size()); + return workspacesList[index]; +} + + +void BScreen::buttonPressEvent(const XButtonEvent *xbutton) { + if (xbutton->button == 1) { + if (! isRootColormapInstalled()) + image_control->installRootColormap(); + + // mouse wheel up + } else if ((xbutton->button == 4 && resource.root_scroll == NormalScroll) || + (xbutton->button == 5 && resource.root_scroll == ReverseScroll)) { + if (getCurrentWorkspaceID() >= getWorkspaceCount() - 1) + changeWorkspaceID(0); + else + changeWorkspaceID(getCurrentWorkspaceID() + 1); + // mouse wheel down + } else if ((xbutton->button == 5 && resource.root_scroll == NormalScroll) || + (xbutton->button == 4 && resource.root_scroll == ReverseScroll)) { + if (getCurrentWorkspaceID() == 0) + changeWorkspaceID(getWorkspaceCount() - 1); + else + changeWorkspaceID(getCurrentWorkspaceID() - 1); + } +} + + +void BScreen::propertyNotifyEvent(const XPropertyEvent *pe) { + if (pe->atom == xatom->atom(otk::OBProperty::net_desktop_names)) { + // _NET_WM_DESKTOP_NAMES + WorkspaceList::iterator it = workspacesList.begin(); + const WorkspaceList::iterator end = workspacesList.end(); + for (; it != end; ++it) { + (*it)->readName(); // re-read its name from the window property + //workspacemenu->changeWorkspaceLabel((*it)->getID(), (*it)->getName()); + } + //workspacemenu->update(); + saveWorkspaceNames(); + } +} + + +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); + } + + std::for_each(windowList.begin(), windowList.end(), + std::mem_fun(&BlackboxWindow::grabButtons)); +} + +} diff --git a/src/bbscreen.hh b/src/bbscreen.hh new file mode 100644 index 00000000..f0bc33d5 --- /dev/null +++ b/src/bbscreen.hh @@ -0,0 +1,268 @@ +// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- +#ifndef __Screen_hh +#define __Screen_hh + +extern "C" { +#include + +#ifdef TIME_WITH_SYS_TIME +# include +# include +#else // !TIME_WITH_SYS_TIME +# ifdef HAVE_SYS_TIME_H +# include +# else // !HAVE_SYS_TIME_H +# include +# endif // HAVE_SYS_TIME_H +#endif // TIME_WITH_SYS_TIME +} + +#include +#include + +#include "otk/color.hh" +#include "otk/font.hh" +#include "otk/texture.hh" +#include "otk/image.hh" +#include "otk/strut.hh" +#include "otk/property.hh" +#include "otk/configuration.hh" +#include "otk/style.hh" +#include "timer.hh" +#include "workspace.hh" +#include "blackbox.hh" + +namespace ob { + +class BScreen : public otk::ScreenInfo { +private: + bool root_colormap_installed, managed, geom_visible; + GC opGC; + Pixmap geom_pixmap; + Window geom_window; + + Blackbox *blackbox; + otk::BImageControl *image_control; + otk::Configuration *config; + otk::OBProperty *xatom; + + BlackboxWindowList iconList, windowList; + + typedef std::vector WindowList; + WindowList specialWindowList, desktopWindowList, systrayWindowList; + + Workspace *current_workspace; + + unsigned int geom_w, geom_h; + unsigned long event_mask; + + otk::Rect usableArea; +#ifdef XINERAMA + RectList xineramaUsableArea; +#endif // XINERAMA + + typedef std::list StrutList; + StrutList strutList; + typedef std::vector WorkspaceList; + WorkspaceList workspacesList; + + struct screen_resource { + otk::Style wstyle; + + bool sloppy_focus, auto_raise, auto_edge_balance, ordered_dither, + opaque_move, full_max, focus_new, focus_last, click_raise, + allow_scroll_lock, window_corner_snap, aa_fonts, + ignore_shaded, ignore_maximized, workspace_warping, shadow_fonts; + + int snap_to_windows, snap_to_edges; + unsigned int snap_offset; + + unsigned int workspaces; + int placement_policy, + snap_threshold, row_direction, col_direction, root_scroll, + resistance_size; + + unsigned int resize_zones; + + std::string strftime_format; + + } resource; + std::string screenstr; + + BScreen(const BScreen&); + BScreen& operator=(const BScreen&); + + void updateWorkArea(void); + +public: + // XXX: temporary + void updateNetizenWorkspaceCount(); + void updateNetizenWindowFocus(); + + + enum { WindowNoSnap = 0, WindowSnap, WindowResistance }; + enum { RowSmartPlacement = 1, ColSmartPlacement, CascadePlacement, + UnderMousePlacement, ClickMousePlacement, LeftRight, RightLeft, + TopBottom, BottomTop, IgnoreShaded, IgnoreMaximized }; + enum { Restart = 1, RestartOther, Exit, Shutdown, Execute, Reconfigure, + WindowShade, WindowIconify, WindowMaximize, WindowClose, WindowRaise, + WindowLower, WindowStick, WindowKill, SetStyle }; + enum FocusModel { SloppyFocus, ClickToFocus }; + enum RootScrollDirection { NoScroll = 0, NormalScroll, ReverseScroll }; + + BScreen(Blackbox *bb, unsigned int scrn); + ~BScreen(void); + + void LoadStyle(void); + + inline bool isSloppyFocus(void) const { return resource.sloppy_focus; } + inline bool isRootColormapInstalled(void) const + { return root_colormap_installed; } + inline bool doAutoRaise(void) const { return resource.auto_raise; } + inline bool doClickRaise(void) const { return resource.click_raise; } + inline bool isScreenManaged(void) const { return managed; } + inline bool doShadowFonts(void) const { return resource.shadow_fonts; } + inline bool doAAFonts(void) const { return resource.aa_fonts; } + inline bool doImageDither(void) const { return image_control->doDither(); } + inline bool doOrderedDither(void) const { return resource.ordered_dither; } + inline bool doOpaqueMove(void) const { return resource.opaque_move; } + inline bool doFullMax(void) const { return resource.full_max; } + inline bool doFocusNew(void) const { return resource.focus_new; } + inline bool doFocusLast(void) const { return resource.focus_last; } + inline int getWindowToWindowSnap(void) const + { return resource.snap_to_windows; } + inline int getWindowToEdgeSnap(void) const + { return resource.snap_to_edges; } + inline bool getWindowCornerSnap(void) const + { return resource.window_corner_snap; } + inline bool allowScrollLock(void) const { return resource.allow_scroll_lock; } + inline bool doWorkspaceWarping(void) const + { return resource.workspace_warping; } + inline int rootScrollDirection(void) const { return resource.root_scroll; } + + inline const GC &getOpGC(void) const { return opGC; } + + inline Blackbox *getBlackbox(void) { return blackbox; } + inline otk::BColor *getBorderColor(void) { + return &resource.wstyle.border_color; + } + inline otk::BImageControl *getImageControl(void) { return image_control; } + + Workspace *getWorkspace(unsigned int index) const; + + inline Workspace *getCurrentWorkspace(void) { return current_workspace; } + + inline unsigned int getResizeZones(void) const + { return resource.resize_zones; } + inline bool getPlaceIgnoreShaded(void) const + { return resource.ignore_shaded; } + inline bool getPlaceIgnoreMaximized(void) const + { return resource.ignore_maximized; } + + inline unsigned int getCurrentWorkspaceID(void) const + { return current_workspace->getID(); } + inline unsigned int getWorkspaceCount(void) const + { return workspacesList.size(); } + inline unsigned int getIconCount(void) const { return iconList.size(); } + inline unsigned int getNumberOfWorkspaces(void) const + { return resource.workspaces; } + inline int getPlacementPolicy(void) const + { return resource.placement_policy; } + inline int getSnapOffset(void) const + { return resource.snap_offset; } + inline int getSnapThreshold(void) const + { return resource.snap_threshold; } + inline int getResistanceSize(void) const + { return resource.resistance_size; } + inline int getRowPlacementDirection(void) const + { return resource.row_direction; } + inline int getColPlacementDirection(void) const + { return resource.col_direction; } + + void changeWorkspaceCount(unsigned int new_count); + + inline void setRootColormapInstalled(bool r) { root_colormap_installed = r; } + void saveSloppyFocus(bool s); + void saveAutoRaise(bool a); + void saveClickRaise(bool c); + void saveWorkspaces(unsigned int w); + void savePlacementPolicy(int p); + void saveRowPlacementDirection(int d); + void saveColPlacementDirection(int d); + void saveSnapThreshold(int t); + void saveSnapOffset(int o); + void saveResistanceSize(int s); + void saveImageDither(bool d); + void saveShadowFonts(bool f); + void saveAAFonts(bool f); + void saveOpaqueMove(bool o); + void saveFullMax(bool f); + void saveFocusNew(bool f); + void saveFocusLast(bool f); + void saveWindowToEdgeSnap(int s); + void saveWindowToWindowSnap(int s); + void saveWindowCornerSnap(bool s); + void saveResizeZones(unsigned int z); + void savePlaceIgnoreShaded(bool i); + void savePlaceIgnoreMaximized(bool i); + void saveAllowScrollLock(bool a); + void saveWorkspaceWarping(bool w); + void saveRootScrollDirection(int d); + + inline const char *getStrftimeFormat(void) + { return resource.strftime_format.c_str(); } + void saveStrftimeFormat(const std::string& format); + + inline otk::Style *getWindowStyle(void) { return &resource.wstyle; } + + BlackboxWindow *getIcon(unsigned int index); + + // allAvailableAreas should be used whenever possible instead of this function + // as then Xinerama will work correctly. + const otk::Rect& availableArea(void) const; +#ifdef XINERAMA + const RectList& allAvailableAreas(void) const; +#endif // XINERAMA + void updateAvailableArea(void); + void addStrut(otk::Strut *strut); + void removeStrut(otk::Strut *strut); + + unsigned int addWorkspace(void); + unsigned int removeLastWorkspace(void); + void changeWorkspaceID(unsigned int id); + void saveWorkspaceNames(void); + + void addSystrayWindow(Window window); + void removeSystrayWindow(Window window); + + void addIcon(BlackboxWindow *w); + void removeIcon(BlackboxWindow *w); + + void updateClientList(void); + void updateStackingList(void); + void manageWindow(Window w); + void unmanageWindow(BlackboxWindow *w, bool remap); + void raiseWindows(Window *workspace_stack, unsigned int num); + void lowerWindows(Window *workspace_stack, unsigned int num); + void reassociateWindow(BlackboxWindow *w, unsigned int wkspc_id, + bool ignore_sticky); + void propagateWindowName(const BlackboxWindow *bw); + void prevFocus(void) const; + void nextFocus(void) const; + void raiseFocus(void) const; + void load_rc(void); + void save_rc(void); + void reconfigure(void); + void toggleFocusModel(FocusModel model); + void shutdown(void); + void showPosition(int x, int y); + void showGeometry(unsigned int gx, unsigned int gy); + void hideGeometry(void); + + void buttonPressEvent(const XButtonEvent *xbutton); + void propertyNotifyEvent(const XPropertyEvent *pe); +}; + +} + +#endif // __Screen_hh diff --git a/src/bbwindow.cc b/src/bbwindow.cc index 82c31aa3..ea0bb55c 100644 --- a/src/bbwindow.cc +++ b/src/bbwindow.cc @@ -27,7 +27,7 @@ extern "C" { #include "font.hh" #include "gccache.hh" #include "image.hh" -#include "screen.hh" +#include "bbscreen.hh" #include "bbwindow.hh" #include "workspace.hh" diff --git a/src/blackbox.cc b/src/blackbox.cc index ce0e550c..bfaefb7c 100644 --- a/src/blackbox.cc +++ b/src/blackbox.cc @@ -79,7 +79,7 @@ using std::string; #include "otk/gccache.hh" #include "otk/image.hh" #include "otk/assassin.hh" -#include "screen.hh" +#include "bbscreen.hh" #include "otk/util.hh" #include "bbwindow.hh" #include "workspace.hh" diff --git a/src/client.cc b/src/client.cc index d6111ce2..f770fecd 100644 --- a/src/client.cc +++ b/src/client.cc @@ -5,7 +5,7 @@ #endif #include "client.hh" -#include "screen.hh" +#include "bbscreen.hh" #include "openbox.hh" #include "otk/display.hh" #include "otk/property.hh" diff --git a/src/frame.hh b/src/frame.hh index 5e7ba927..f1632981 100644 --- a/src/frame.hh +++ b/src/frame.hh @@ -9,14 +9,14 @@ extern "C" { #include } -#include - #include "client.hh" #include "otk/strut.hh" #include "otk/rect.hh" #include "otk/screeninfo.hh" #include "otk/style.hh" +#include + namespace ob { //! Holds and decorates a frame around an OBClient (client window) diff --git a/src/screen.cc b/src/screen.cc deleted file mode 100644 index d6350c2e..00000000 --- a/src/screen.cc +++ /dev/null @@ -1,1555 +0,0 @@ -// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- - -#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 - -#ifdef HAVE_STRING_H -# include -#endif // HAVE_STRING_H - -#ifdef HAVE_CTYPE_H -# include -#endif // HAVE_CTYPE_H - -#ifdef HAVE_UNISTD_H -# include -# include -#endif // HAVE_UNISTD_H - -#ifdef HAVE_DIRENT_H -# include -#endif // HAVE_DIRENT_H - -#ifdef HAVE_LOCALE_H -# include -#endif // HAVE_LOCALE_H - -#ifdef HAVE_SYS_STAT_H -# include -#endif // HAVE_SYS_STAT_H - -#ifdef HAVE_STDARG_H -# include -#endif // HAVE_STDARG_H -} - -#include - -#include -#include -#include -using std::string; - -#include "screen.hh" -#include "otk/font.hh" -#include "otk/gccache.hh" -#include "otk/image.hh" -#include "otk/assassin.hh" -#include "otk/util.hh" -#include "openbox.hh" -#include "bbwindow.hh" -#include "workspace.hh" - -#ifndef FONT_ELEMENT_SIZE -#define FONT_ELEMENT_SIZE 50 -#endif // FONT_ELEMENT_SIZE - -namespace ob { - -static bool running = True; - -static int anotherWMRunning(Display *display, XErrorEvent *) { - fprintf(stderr, - "BScreen::BScreen: an error occured while querying the X server.\n" - " another window manager already running on display %s.\n", - DisplayString(display)); - - running = False; - - return(-1); -} - - -BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(scrn) { - blackbox = bb; - screenstr = "session.screen" + otk::itostring(scrn) + '.'; - config = blackbox->getConfig(); - xatom = blackbox->getXAtom(); - - event_mask = ColormapChangeMask | EnterWindowMask | PropertyChangeMask | - SubstructureRedirectMask | ButtonPressMask | ButtonReleaseMask; - - XErrorHandler old = XSetErrorHandler((XErrorHandler) anotherWMRunning); - XSelectInput(otk::OBDisplay::display, getRootWindow(), event_mask); - XSync(otk::OBDisplay::display, False); - XSetErrorHandler((XErrorHandler) old); - - managed = running; - if (! managed) return; - - fprintf(stderr, "BScreen::BScreen: managing screen %d " - "using visual 0x%lx, depth %d\n", - getScreenNumber(), XVisualIDFromVisual(getVisual()), - getDepth()); - - resource.wstyle.font = (otk::BFont *) 0; - - geom_pixmap = None; - -// xatom->setSupported(this); // set-up netwm support -#ifdef HAVE_GETPID - xatom->setValue(getRootWindow(), otk::OBProperty::blackbox_pid, - otk::OBProperty::Atom_Cardinal, - (unsigned long) getpid()); -#endif // HAVE_GETPID - unsigned long geometry[] = { getWidth(), - getHeight()}; - xatom->set(getRootWindow(), otk::OBProperty::net_desktop_geometry, - otk::OBProperty::Atom_Cardinal, geometry, 2); - unsigned long viewport[] = {0,0}; - xatom->set(getRootWindow(), otk::OBProperty::net_desktop_viewport, - otk::OBProperty::Atom_Cardinal, viewport, 2); - - - XDefineCursor(otk::OBDisplay::display, getRootWindow(), - blackbox->getSessionCursor()); - - updateAvailableArea(); - - image_control = - new otk::BImageControl(Openbox::instance->timerManager(), - this, True, blackbox->getColorsPerChannel(), - blackbox->getCacheLife(), blackbox->getCacheMax()); - image_control->installRootColormap(); - root_colormap_installed = True; - - load_rc(); - - // XXX: ugh - resource.wstyle.setImageControl(image_control); - resource.wstyle.setScreenNumber(scrn); - LoadStyle(); - - XGCValues gcv; - gcv.foreground = WhitePixel(otk::OBDisplay::display, getScreenNumber()) - ^ BlackPixel(otk::OBDisplay::display, getScreenNumber()); - gcv.function = GXxor; - gcv.subwindow_mode = IncludeInferiors; - opGC = XCreateGC(otk::OBDisplay::display, getRootWindow(), - GCForeground | GCFunction | GCSubwindowMode, &gcv); - - const char *s = "0: 0000 x 0: 0000"; - geom_w = resource.wstyle.font->measureString(s) + resource.wstyle.bevel_width * 2; - geom_h = resource.wstyle.font->height() + resource.wstyle.bevel_width * 2; - - XSetWindowAttributes attrib; - unsigned long mask = CWBorderPixel | CWColormap | CWSaveUnder; - attrib.border_pixel = getBorderColor()->pixel(); - attrib.colormap = getColormap(); - attrib.save_under = True; - - // XXX -- move this geom_* crap out of here - - geom_window = XCreateWindow(otk::OBDisplay::display, getRootWindow(), - 0, 0, geom_w, geom_h, resource.wstyle.border_width, - getDepth(), InputOutput, getVisual(), - mask, &attrib); - geom_visible = False; - - otk::BTexture* texture = &(resource.wstyle.l_focus); - geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap); - if (geom_pixmap == ParentRelative) { - texture = &(resource.wstyle.t_focus); - geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap); - } - if (! geom_pixmap) - XSetWindowBackground(otk::OBDisplay::display, geom_window, - texture->color().pixel()); - else - XSetWindowBackgroundPixmap(otk::OBDisplay::display, - geom_window, geom_pixmap); - - if (resource.workspaces > 0) { - for (unsigned int i = 0; i < resource.workspaces; ++i) { - Workspace *wkspc = new Workspace(this, workspacesList.size()); - workspacesList.push_back(wkspc); - - } - } else { - Workspace *wkspc = new Workspace(this, workspacesList.size()); - workspacesList.push_back(wkspc); - } - - // /GEOM_PIXMAP - - saveWorkspaceNames(); - - updateNetizenWorkspaceCount(); - - current_workspace = workspacesList.front(); - - xatom->set(getRootWindow(), otk::OBProperty::net_current_desktop, - otk::OBProperty::Atom_Cardinal, 0); //first workspace - - raiseWindows(0, 0); // this also initializes the empty stacking list - - updateClientList(); // initialize the client lists, which will be empty - updateAvailableArea(); - - changeWorkspaceID(0); - - unsigned int i, j, nchild; - Window r, p, *children; - XQueryTree(otk::OBDisplay::display, getRootWindow(), &r, &p, - &children, &nchild); - - // preen the window list of all icon windows... for better dockapp support - for (i = 0; i < nchild; i++) { - if (children[i] == None) continue; - - XWMHints *wmhints = XGetWMHints(otk::OBDisplay::display, - children[i]); - - if (wmhints) { - if ((wmhints->flags & IconWindowHint) && - (wmhints->icon_window != children[i])) { - for (j = 0; j < nchild; j++) { - if (children[j] == wmhints->icon_window) { - children[j] = None; - break; - } - } - } - - XFree(wmhints); - } - } - - // manage shown windows - for (i = 0; i < nchild; ++i) { - if (children[i] == None || ! blackbox->validateWindow(children[i])) - continue; - - XWindowAttributes attrib; - if (XGetWindowAttributes(otk::OBDisplay::display, children[i], &attrib)) { - if (attrib.override_redirect) continue; - - if (attrib.map_state != IsUnmapped) { - manageWindow(children[i]); - } - } - } - - XFree(children); - - // call this again just in case a window we found updates the Strut list - updateAvailableArea(); -} - - -BScreen::~BScreen(void) { - if (! managed) return; - - if (geom_pixmap != None) - image_control->removeImage(geom_pixmap); - - if (geom_window != None) - XDestroyWindow(otk::OBDisplay::display, geom_window); - - std::for_each(workspacesList.begin(), workspacesList.end(), - otk::PointerAssassin()); - - std::for_each(iconList.begin(), iconList.end(), otk::PointerAssassin()); - - while (! systrayWindowList.empty()) - removeSystrayWindow(systrayWindowList[0]); - - delete image_control; - - // delete style - - XFreeGC(otk::OBDisplay::display, opGC); -} - - -void BScreen::LoadStyle(void) { - otk::Configuration style_conf(False); - - const char *sfile = blackbox->getStyleFilename(); - if (sfile != NULL) { - style_conf.setFile(sfile); - if (! style_conf.load()) { - style_conf.setFile(DEFAULTSTYLE); - if (! style_conf.load()) - style_conf.create(); // hardcoded default values will be used. - } - } - - // merge in the rc file - style_conf.merge(config->file(), True); - - resource.wstyle.load(style_conf); -} - -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::saveAAFonts(bool f) { - resource.aa_fonts = f; - config->setValue(screenstr + "antialiasFonts", resource.aa_fonts); - reconfigure(); -} - - -void BScreen::saveShadowFonts(bool f) { - resource.shadow_fonts = f; - config->setValue(screenstr + "dropShadowFonts", resource.shadow_fonts); - reconfigure(); -} - - -void BScreen::saveWindowToEdgeSnap(int s) { - resource.snap_to_edges = s; - - const char *snap; - switch (resource.snap_to_edges) { - case WindowNoSnap: snap = "NoSnap"; break; - case WindowResistance: snap = "Resistance"; break; - case WindowSnap: default: snap = "Snap"; break; - } - config->setValue(screenstr + "windowToEdgeSnap", snap); -} - - -void BScreen::saveWindowToWindowSnap(int s) { - resource.snap_to_windows = s; - - const char *snap; - switch (resource.snap_to_windows) { - case WindowNoSnap: snap = "NoSnap"; break; - case WindowResistance: snap = "Resistance"; break; - case WindowSnap: default: snap = "Snap"; break; - } - config->setValue(screenstr + "windowToWindowSnap", snap); -} - - -void BScreen::saveResizeZones(unsigned int z) { - resource.resize_zones = z; - config->setValue(screenstr + "resizeZones", resource.resize_zones); -} - - -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 UnderMousePlacement: placement = "UnderMousePlacement"; break; - case ClickMousePlacement: placement = "ClickMousePlacement"; break; - case ColSmartPlacement: placement = "ColSmartPlacement"; break; - case RowSmartPlacement: default: placement = "RowSmartPlacement"; break; - } - config->setValue(screenstr + "windowPlacement", placement); -} - - -void BScreen::saveResistanceSize(int s) { - resource.resistance_size = s; - config->setValue(screenstr + "resistanceSize", - resource.resistance_size); -} - - -void BScreen::saveSnapThreshold(int t) { - resource.snap_threshold = t; - config->setValue(screenstr + "edgeSnapThreshold", - resource.snap_threshold); -} - - -void BScreen::saveSnapOffset(int t) { - resource.snap_offset = t; - config->setValue(screenstr + "edgeSnapOffset", - resource.snap_offset); -} - - -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"); -} - - -void BScreen::saveStrftimeFormat(const std::string& format) { - resource.strftime_format = format; - config->setValue(screenstr + "strftimeFormat", resource.strftime_format); -} - - -void BScreen::saveWorkspaceNames() { - string names; - - for (unsigned int i = 0; i < workspacesList.size(); ++i) { - names += workspacesList[i]->getName(); - if (i < workspacesList.size() - 1) - names += ','; - } - - config->setValue(screenstr + "workspaceNames", names); -} - - -void BScreen::savePlaceIgnoreShaded(bool i) { - resource.ignore_shaded = i; - config->setValue(screenstr + "placementIgnoreShaded", - resource.ignore_shaded); -} - - -void BScreen::savePlaceIgnoreMaximized(bool i) { - resource.ignore_maximized = i; - config->setValue(screenstr + "placementIgnoreMaximized", - resource.ignore_maximized); -} - - -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::saveRootScrollDirection(int d) { - resource.root_scroll = d; - const char *dir; - switch (resource.root_scroll) { - case NoScroll: dir = "None"; break; - case ReverseScroll: dir = "Reverse"; break; - case NormalScroll: default: dir = "Normal"; break; - } - config->setValue(screenstr + "rootScrollDirection", dir); -} - - -void BScreen::save_rc(void) { - saveSloppyFocus(resource.sloppy_focus); - saveAutoRaise(resource.auto_raise); - saveImageDither(doImageDither()); - saveShadowFonts(resource.shadow_fonts); - saveAAFonts(resource.aa_fonts); - saveResizeZones(resource.resize_zones); - saveOpaqueMove(resource.opaque_move); - saveFullMax(resource.full_max); - saveFocusNew(resource.focus_new); - saveFocusLast(resource.focus_last); - saveWindowToWindowSnap(resource.snap_to_windows); - saveWindowToEdgeSnap(resource.snap_to_edges); - saveWindowCornerSnap(resource.window_corner_snap); - saveWorkspaces(resource.workspaces); - savePlacementPolicy(resource.placement_policy); - saveSnapThreshold(resource.snap_threshold); - saveSnapOffset(resource.snap_offset); - saveResistanceSize(resource.resistance_size); - saveRowPlacementDirection(resource.row_direction); - saveColPlacementDirection(resource.col_direction); - saveStrftimeFormat(resource.strftime_format); - savePlaceIgnoreShaded(resource.ignore_shaded); - savePlaceIgnoreMaximized(resource.ignore_maximized); - saveAllowScrollLock(resource.allow_scroll_lock); - saveWorkspaceWarping(resource.workspace_warping); - saveRootScrollDirection(resource.root_scroll); -} - - -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 + "antialiasFonts", resource.aa_fonts)) - resource.aa_fonts = true; - - if (! resource.aa_fonts || - ! config->getValue(screenstr + "dropShadowFonts", resource.shadow_fonts)) - resource.shadow_fonts = false; - - if (! config->getValue(screenstr + "resizeZones", resource.resize_zones) || - (resource.resize_zones != 1 && resource.resize_zones != 2 && - resource.resize_zones != 4)) - resource.resize_zones = 4; - - resource.snap_to_windows = WindowResistance; - if (config->getValue(screenstr + "windowToWindowSnap", s)) { - if (s == "NoSnap") - resource.snap_to_windows = WindowNoSnap; - else if (s == "Snap") - resource.snap_to_windows = WindowSnap; - } - - resource.snap_to_edges = WindowResistance; - if (config->getValue(screenstr + "windowToEdgeSnap", s)) { - if (s == "NoSnap") - resource.snap_to_edges = WindowNoSnap; - else if (s == "Snap") - resource.snap_to_edges = WindowSnap; - } - - 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 + "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)) - resource.snap_threshold = 4; - - if (! config->getValue(screenstr + "resistanceSize", - resource.resistance_size)) - resource.resistance_size = 18; - - 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; - - if (config->getValue(screenstr + "workspaceNames", s)) { - otk::OBProperty::StringVect workspaceNames; - - 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->set(getRootWindow(), otk::OBProperty::net_desktop_names, - otk::OBProperty::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 == "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") - resource.placement_policy = RowSmartPlacement; - } else - resource.placement_policy = RowSmartPlacement; - - if (! config->getValue(screenstr + "strftimeFormat", - resource.strftime_format)) - resource.strftime_format = "%I:%M %p"; - - if (! config->getValue(screenstr + "placementIgnoreShaded", - resource.ignore_shaded)) - resource.ignore_shaded = true; - - 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; - - resource.root_scroll = NormalScroll; - if (config->getValue(screenstr + "rootScrollDirection", s)) { - if (s == "None") - resource.root_scroll = NoScroll; - else if (s == "Reverse") - resource.root_scroll = ReverseScroll; - } -} - - -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->state() == Openbox::State_Starting) return; - - 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(otk::OBDisplay::display, - getScreenNumber()); - gcv.function = GXinvert; - gcv.subwindow_mode = IncludeInferiors; - XChangeGC(otk::OBDisplay::display, opGC, - GCForeground | GCFunction | GCSubwindowMode, &gcv); - - const char *s = "0: 0000 x 0: 0000"; - - geom_w = resource.wstyle.font->measureString(s) + resource.wstyle.bevel_width * 2; - geom_h = resource.wstyle.font->height() + resource.wstyle.bevel_width * 2; - - otk::BTexture* texture = &(resource.wstyle.l_focus); - geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap); - if (geom_pixmap == ParentRelative) { - texture = &(resource.wstyle.t_focus); - geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap); - } - if (! geom_pixmap) - XSetWindowBackground(otk::OBDisplay::display, geom_window, - texture->color().pixel()); - else - XSetWindowBackgroundPixmap(otk::OBDisplay::display, - geom_window, geom_pixmap); - - XSetWindowBorderWidth(otk::OBDisplay::display, geom_window, - resource.wstyle.border_width); - XSetWindowBorder(otk::OBDisplay::display, geom_window, - resource.wstyle.border_color.pixel()); - - typedef std::vector SubList; - SubList remember_subs; - - raiseWindows(0, 0); - - std::for_each(workspacesList.begin(), workspacesList.end(), - std::mem_fun(&Workspace::reconfigure)); - - BlackboxWindowList::iterator iit = iconList.begin(); - for (; iit != iconList.end(); ++iit) { - BlackboxWindow *bw = *iit; - if (bw->validateClient()) - bw->reconfigure(); - } - - otk::BImageControl::timeout(image_control); -} - - - -void BScreen::addIcon(BlackboxWindow *w) { - if (! w) return; - - w->setWorkspace(otk::BSENTINEL); - w->setWindowNumber(iconList.size()); - - iconList.push_back(w); -} - - -void BScreen::removeIcon(BlackboxWindow *w) { - if (! w) return; - - iconList.remove(w); - - BlackboxWindowList::iterator it = iconList.begin(), - end = iconList.end(); - for (int i = 0; it != end; ++it) - (*it)->setWindowNumber(i++); -} - - -BlackboxWindow *BScreen::getIcon(unsigned int index) { - if (index < iconList.size()) { - BlackboxWindowList::iterator it = iconList.begin(); - while (index-- > 0) // increment to index - ++it; - return *it; - } - - return (BlackboxWindow *) 0; -} - - -unsigned int BScreen::addWorkspace(void) { - Workspace *wkspc = new Workspace(this, workspacesList.size()); - workspacesList.push_back(wkspc); - saveWorkspaces(getWorkspaceCount()); - saveWorkspaceNames(); - - return workspacesList.size(); -} - - -unsigned int BScreen::removeLastWorkspace(void) { - if (workspacesList.size() == 1) - return 1; - - Workspace *wkspc = workspacesList.back(); - - if (current_workspace->getID() == wkspc->getID()) - changeWorkspaceID(current_workspace->getID() - 1); - - wkspc->removeAll(); - - workspacesList.pop_back(); - delete wkspc; - - saveWorkspaces(getWorkspaceCount()); - saveWorkspaceNames(); - - updateNetizenWorkspaceCount(); - - return workspacesList.size(); -} - - -void BScreen::changeWorkspaceID(unsigned int id) { - if (! current_workspace || id == current_workspace->getID()) return; - - BlackboxWindow *focused = blackbox->getFocusedWindow(); - if (focused && focused->getScreen() == this) { - assert(focused->isStuck() || - focused->getWorkspaceNumber() == current_workspace->getID()); - - 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 if it is going - // to be unmapped - if (focused && ! focused->isStuck()) - blackbox->setFocusedWindow((BlackboxWindow *) 0); - - current_workspace->hideAll(); - - current_workspace = getWorkspace(id); - - xatom->set(getRootWindow(), otk::OBProperty::net_current_desktop, - otk::OBProperty::Atom_Cardinal, id); - - current_workspace->showAll(); - - int x, y, rx, ry; - Window c, r; - unsigned int m; - BlackboxWindow *win = (BlackboxWindow *) 0; - bool f = False; - - XSync(otk::OBDisplay::display, False); - - // If sloppy focus and we can find the client window under the pointer, - // try to focus it. - if (resource.sloppy_focus && - XQueryPointer(otk::OBDisplay::display, 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); -} - - -/* - * 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->set(getRootWindow(), otk::OBProperty::net_client_list, - otk::OBProperty::Atom_Window, windows, windowList.size()); - delete [] windows; - } else - xatom->set(getRootWindow(), otk::OBProperty::net_client_list, - otk::OBProperty::Atom_Window, 0, 0); - - updateStackingList(); -} - - -/* - * Set the _NET_CLIENT_LIST_STACKING root window property. - */ -void BScreen::updateStackingList(void) { - - BlackboxWindowList stack_order; - - /* - * Get the stacking 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(), - end = stack_order.end(); - for (; it != end; ++it, ++win_it) - *win_it = (*it)->getClientWindow(); - xatom->set(getRootWindow(), otk::OBProperty::net_client_list_stacking, - otk::OBProperty::Atom_Window, windows, stack_order.size()); - delete [] windows; - } else - xatom->set(getRootWindow(), otk::OBProperty::net_client_list_stacking, - otk::OBProperty::Atom_Window, 0, 0); -} - - -void BScreen::addSystrayWindow(Window window) { - XGrabServer(otk::OBDisplay::display); - - XSelectInput(otk::OBDisplay::display, window, StructureNotifyMask); - systrayWindowList.push_back(window); - xatom->set(getRootWindow(), otk::OBProperty::kde_net_system_tray_windows, - otk::OBProperty::Atom_Window, - &systrayWindowList[0], systrayWindowList.size()); - blackbox->saveSystrayWindowSearch(window, this); - - XUngrabServer(otk::OBDisplay::display); -} - - -void BScreen::removeSystrayWindow(Window window) { - XGrabServer(otk::OBDisplay::display); - - WindowList::iterator it = systrayWindowList.begin(); - const WindowList::iterator end = systrayWindowList.end(); - for (; it != end; ++it) - if (*it == window) { - systrayWindowList.erase(it); - xatom->set(getRootWindow(), - otk::OBProperty::kde_net_system_tray_windows, - otk::OBProperty::Atom_Window, - &systrayWindowList[0], systrayWindowList.size()); - blackbox->removeSystrayWindowSearch(window); - XSelectInput(otk::OBDisplay::display, window, NoEventMask); - break; - } - - assert(it != end); // not a systray window - - XUngrabServer(otk::OBDisplay::display); -} - - -void BScreen::manageWindow(Window w) { - // is the window a KDE systray window? - Window systray; - if (xatom->get(w, otk::OBProperty::kde_net_wm_system_tray_window_for, - otk::OBProperty::Atom_Window, &systray) && - systray != None) - { - addSystrayWindow(w); - return; - } - - // is the window a docking app - XWMHints *wmhint = XGetWMHints(otk::OBDisplay::display, w); - if (wmhint && (wmhint->flags & StateHint) && - wmhint->initial_state == WithdrawnState) { - //slit->addClient(w); - return; - } - - new BlackboxWindow(blackbox, w, this); - - BlackboxWindow *win = blackbox->searchWindow(w); - if (! win) - return; - - 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(); - - if (win->isTopmost()) - specialWindowList.push_back(win->getFrameWindow()); - } - - XMapRequestEvent mre; - mre.window = w; - if (blackbox->state() == Openbox::State_Starting && - win->isNormal()) - win->restoreAttributes(); - win->mapRequestEvent(&mre); -} - - -void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) { - // is the window a KDE systray window? - Window systray; - if (xatom->get(w->getClientWindow(), - otk::OBProperty::kde_net_wm_system_tray_window_for, - otk::OBProperty::Atom_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 - if (w->isModal()) w->setModal(False); - - if (w->getWorkspaceNumber() != otk::BSENTINEL && - w->getWindowNumber() != otk::BSENTINEL) { - getWorkspace(w->getWorkspaceNumber())->removeWindow(w); - if (w->isStuck()) { - for (unsigned int i = 0; i < getNumberOfWorkspaces(); ++i) - if (i != w->getWorkspaceNumber()) - getWorkspace(i)->removeWindow(w, True); - } - } else if (w->isIconic()) - removeIcon(w); - - 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? - } 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) - blackbox->setFocusedWindow((BlackboxWindow *) 0); - - /* - 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; -} - - -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 otk::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->set(getRootWindow(), otk::OBProperty::net_workarea, - otk::OBProperty::Atom_Cardinal, - dims, 4 * workspacesList.size()); - delete [] dims; - } else - xatom->set(getRootWindow(), otk::OBProperty::net_workarea, - otk::OBProperty::Atom_Cardinal, 0, 0); -} - - -void BScreen::updateNetizenWorkspaceCount(void) { - xatom->set(getRootWindow(), otk::OBProperty::net_number_of_desktops, - otk::OBProperty::Atom_Cardinal, workspacesList.size()); - - updateWorkArea(); -} - - -void BScreen::updateNetizenWindowFocus(void) { - Window f = ((blackbox->getFocusedWindow()) ? - blackbox->getFocusedWindow()->getClientWindow() : None); - - xatom->set(getRootWindow(), otk::OBProperty::net_active_window, - otk::OBProperty::Atom_Window, f); -} - - -void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) { - // the 13 represents the number of blackbox windows such as menus - int bbwins = 15; -#ifdef XINERAMA - ++bbwins; -#endif // XINERAMA - - Window *session_stack = new - Window[(num + specialWindowList.size() + bbwins)]; - unsigned int i = 0, k = num; - - 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); - - XRestackWindows(otk::OBDisplay::display, session_stack, i); - - delete [] session_stack; - - updateStackingList(); -} - - -void BScreen::lowerWindows(Window *workspace_stack, unsigned int num) { - assert(num > 0); // this would cause trouble in the XRaiseWindow call - - Window *session_stack = new Window[(num + desktopWindowList.size())]; - unsigned int i = 0, k = num; - - XLowerWindow(otk::OBDisplay::display, workspace_stack[0]); - - while (k--) - *(session_stack + i++) = *(workspace_stack + k); - - WindowList::iterator dit = desktopWindowList.begin(); - const WindowList::iterator d_end = desktopWindowList.end(); - for (; dit != d_end; ++dit) - *(session_stack + i++) = *dit; - - XRestackWindows(otk::OBDisplay::display, session_stack, i); - - delete [] session_stack; - - updateStackingList(); -} - - -void BScreen::reassociateWindow(BlackboxWindow *w, unsigned int wkspc_id, - bool ignore_sticky) { - if (! w) return; - - if (wkspc_id == otk::BSENTINEL) - wkspc_id = current_workspace->getID(); - - if (w->getWorkspaceNumber() == wkspc_id) - return; - - if (w->isIconic()) { - removeIcon(w); - getWorkspace(wkspc_id)->addWindow(w); - if (w->isStuck()) - for (unsigned int i = 0; i < getNumberOfWorkspaces(); ++i) - if (i != w->getWorkspaceNumber()) - getWorkspace(i)->addWindow(w, True); - } else if (ignore_sticky || ! w->isStuck()) { - if (w->isStuck()) - w->stick(); - getWorkspace(w->getWorkspaceNumber())->removeWindow(w); - getWorkspace(wkspc_id)->addWindow(w); - } - updateStackingList(); -} - - -void BScreen::propagateWindowName(const BlackboxWindow *bw) { - if (bw->isIconic()) { - } else { - } -} - - -void BScreen::nextFocus(void) const { - BlackboxWindow *focused = blackbox->getFocusedWindow(), - *next = focused; - - if (focused && - focused->getScreen()->getScreenNumber() == getScreenNumber() && - current_workspace->getCount() > 1) { - do { - next = current_workspace->getNextWindowInList(next); - } while (next != focused && ! next->setInputFocus()); - - if (next != focused) - current_workspace->raiseWindow(next); - } else if (current_workspace->getCount() > 0) { - next = current_workspace->getTopWindowOnStack(); - next->setInputFocus(); - current_workspace->raiseWindow(next); - } -} - - -void BScreen::prevFocus(void) const { - BlackboxWindow *focused = blackbox->getFocusedWindow(), - *next = focused; - - if (focused) { - // if window is not on this screen, ignore it - if (focused->getScreen()->getScreenNumber() != getScreenNumber()) - focused = (BlackboxWindow*) 0; - } - - if (focused && - focused->getScreen()->getScreenNumber() == getScreenNumber() && - current_workspace->getCount() > 1) { - // next is the next window to receive focus, current is a place holder - do { - next = current_workspace->getPrevWindowInList(next); - } while (next != focused && ! next->setInputFocus()); - - if (next != focused) - current_workspace->raiseWindow(next); - } else if (current_workspace->getCount() > 0) { - next = current_workspace->getTopWindowOnStack(); - next->setInputFocus(); - current_workspace->raiseWindow(next); - } -} - - -void BScreen::raiseFocus(void) const { - BlackboxWindow *focused = blackbox->getFocusedWindow(); - if (! focused) - return; - - // if on this Screen, raise it - if (focused->getScreen()->getScreenNumber() == getScreenNumber()) { - Workspace *workspace = getWorkspace(focused->getWorkspaceNumber()); - workspace->raiseWindow(focused); - } -} - - -void BScreen::shutdown(void) { - XSelectInput(otk::OBDisplay::display, getRootWindow(), NoEventMask); - XSync(otk::OBDisplay::display, False); - - while(! windowList.empty()) - unmanageWindow(windowList.front(), True); - - while(! desktopWindowList.empty()) { - BlackboxWindow *win = blackbox->searchWindow(desktopWindowList.front()); - assert(win); - unmanageWindow(win, True); - } -} - - -void BScreen::showPosition(int x, int y) { - if (! geom_visible) { - XMoveResizeWindow(otk::OBDisplay::display, geom_window, - (getWidth() - geom_w) / 2, - (getHeight() - geom_h) / 2, geom_w, geom_h); - XMapWindow(otk::OBDisplay::display, geom_window); - XRaiseWindow(otk::OBDisplay::display, geom_window); - - geom_visible = True; - } - - char label[1024]; - - sprintf(label, "X: %4d x Y: %4d", x, y); - - XClearWindow(otk::OBDisplay::display, geom_window); - - resource.wstyle.font->drawString(geom_window, - resource.wstyle.bevel_width, resource.wstyle.bevel_width, - resource.wstyle.l_text_focus, - label); -} - - -void BScreen::showGeometry(unsigned int gx, unsigned int gy) { - if (! geom_visible) { - XMoveResizeWindow(otk::OBDisplay::display, geom_window, - (getWidth() - geom_w) / 2, - (getHeight() - geom_h) / 2, geom_w, geom_h); - XMapWindow(otk::OBDisplay::display, geom_window); - XRaiseWindow(otk::OBDisplay::display, geom_window); - - geom_visible = True; - } - - char label[1024]; - - sprintf(label, "W: %4d x H: %4d", gx, gy); - - XClearWindow(otk::OBDisplay::display, geom_window); - - resource.wstyle.font->drawString(geom_window, - resource.wstyle.bevel_width, resource.wstyle.bevel_width, - resource.wstyle.l_text_focus, - label); -} - - -void BScreen::hideGeometry(void) { - if (geom_visible) { - XUnmapWindow(otk::OBDisplay::display, geom_window); - geom_visible = False; - } -} - - -void BScreen::addStrut(otk::Strut *strut) { - strutList.push_back(strut); -} - - -void BScreen::removeStrut(otk::Strut *strut) { - strutList.remove(strut); -} - - -const otk::Rect& BScreen::availableArea(void) const { - if (doFullMax()) - return getRect(); // return the full screen - return usableArea; -} - - -#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) { - otk::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 - * do not be confused by the similarity to the names of Rect's members - */ - unsigned int current_left = 0, current_right = 0, current_top = 0, - current_bottom = 0; - - StrutList::const_iterator it = strutList.begin(), end = strutList.end(); - - for(; it != end; ++it) { - otk::Strut *strut = *it; - if (strut->left > current_left) - current_left = strut->left; - if (strut->top > current_top) - current_top = strut->top; - if (strut->right > current_right) - current_right = strut->right; - if (strut->bottom > current_bottom) - current_bottom = strut->bottom; - } - - usableArea.setPos(current_left, current_top); - 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(); - for (; it != end; ++it) - if ((*it)->isMaximized()) (*it)->remaximize(); - } - - updateWorkArea(); -} - - -Workspace* BScreen::getWorkspace(unsigned int index) const { - assert(index < workspacesList.size()); - return workspacesList[index]; -} - - -void BScreen::buttonPressEvent(const XButtonEvent *xbutton) { - if (xbutton->button == 1) { - if (! isRootColormapInstalled()) - image_control->installRootColormap(); - - // mouse wheel up - } else if ((xbutton->button == 4 && resource.root_scroll == NormalScroll) || - (xbutton->button == 5 && resource.root_scroll == ReverseScroll)) { - if (getCurrentWorkspaceID() >= getWorkspaceCount() - 1) - changeWorkspaceID(0); - else - changeWorkspaceID(getCurrentWorkspaceID() + 1); - // mouse wheel down - } else if ((xbutton->button == 5 && resource.root_scroll == NormalScroll) || - (xbutton->button == 4 && resource.root_scroll == ReverseScroll)) { - if (getCurrentWorkspaceID() == 0) - changeWorkspaceID(getWorkspaceCount() - 1); - else - changeWorkspaceID(getCurrentWorkspaceID() - 1); - } -} - - -void BScreen::propertyNotifyEvent(const XPropertyEvent *pe) { - if (pe->atom == xatom->atom(otk::OBProperty::net_desktop_names)) { - // _NET_WM_DESKTOP_NAMES - WorkspaceList::iterator it = workspacesList.begin(); - const WorkspaceList::iterator end = workspacesList.end(); - for (; it != end; ++it) { - (*it)->readName(); // re-read its name from the window property - //workspacemenu->changeWorkspaceLabel((*it)->getID(), (*it)->getName()); - } - //workspacemenu->update(); - saveWorkspaceNames(); - } -} - - -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); - } - - std::for_each(windowList.begin(), windowList.end(), - std::mem_fun(&BlackboxWindow::grabButtons)); -} - -} diff --git a/src/screen.hh b/src/screen.hh deleted file mode 100644 index f0bc33d5..00000000 --- a/src/screen.hh +++ /dev/null @@ -1,268 +0,0 @@ -// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- -#ifndef __Screen_hh -#define __Screen_hh - -extern "C" { -#include - -#ifdef TIME_WITH_SYS_TIME -# include -# include -#else // !TIME_WITH_SYS_TIME -# ifdef HAVE_SYS_TIME_H -# include -# else // !HAVE_SYS_TIME_H -# include -# endif // HAVE_SYS_TIME_H -#endif // TIME_WITH_SYS_TIME -} - -#include -#include - -#include "otk/color.hh" -#include "otk/font.hh" -#include "otk/texture.hh" -#include "otk/image.hh" -#include "otk/strut.hh" -#include "otk/property.hh" -#include "otk/configuration.hh" -#include "otk/style.hh" -#include "timer.hh" -#include "workspace.hh" -#include "blackbox.hh" - -namespace ob { - -class BScreen : public otk::ScreenInfo { -private: - bool root_colormap_installed, managed, geom_visible; - GC opGC; - Pixmap geom_pixmap; - Window geom_window; - - Blackbox *blackbox; - otk::BImageControl *image_control; - otk::Configuration *config; - otk::OBProperty *xatom; - - BlackboxWindowList iconList, windowList; - - typedef std::vector WindowList; - WindowList specialWindowList, desktopWindowList, systrayWindowList; - - Workspace *current_workspace; - - unsigned int geom_w, geom_h; - unsigned long event_mask; - - otk::Rect usableArea; -#ifdef XINERAMA - RectList xineramaUsableArea; -#endif // XINERAMA - - typedef std::list StrutList; - StrutList strutList; - typedef std::vector WorkspaceList; - WorkspaceList workspacesList; - - struct screen_resource { - otk::Style wstyle; - - bool sloppy_focus, auto_raise, auto_edge_balance, ordered_dither, - opaque_move, full_max, focus_new, focus_last, click_raise, - allow_scroll_lock, window_corner_snap, aa_fonts, - ignore_shaded, ignore_maximized, workspace_warping, shadow_fonts; - - int snap_to_windows, snap_to_edges; - unsigned int snap_offset; - - unsigned int workspaces; - int placement_policy, - snap_threshold, row_direction, col_direction, root_scroll, - resistance_size; - - unsigned int resize_zones; - - std::string strftime_format; - - } resource; - std::string screenstr; - - BScreen(const BScreen&); - BScreen& operator=(const BScreen&); - - void updateWorkArea(void); - -public: - // XXX: temporary - void updateNetizenWorkspaceCount(); - void updateNetizenWindowFocus(); - - - enum { WindowNoSnap = 0, WindowSnap, WindowResistance }; - enum { RowSmartPlacement = 1, ColSmartPlacement, CascadePlacement, - UnderMousePlacement, ClickMousePlacement, LeftRight, RightLeft, - TopBottom, BottomTop, IgnoreShaded, IgnoreMaximized }; - enum { Restart = 1, RestartOther, Exit, Shutdown, Execute, Reconfigure, - WindowShade, WindowIconify, WindowMaximize, WindowClose, WindowRaise, - WindowLower, WindowStick, WindowKill, SetStyle }; - enum FocusModel { SloppyFocus, ClickToFocus }; - enum RootScrollDirection { NoScroll = 0, NormalScroll, ReverseScroll }; - - BScreen(Blackbox *bb, unsigned int scrn); - ~BScreen(void); - - void LoadStyle(void); - - inline bool isSloppyFocus(void) const { return resource.sloppy_focus; } - inline bool isRootColormapInstalled(void) const - { return root_colormap_installed; } - inline bool doAutoRaise(void) const { return resource.auto_raise; } - inline bool doClickRaise(void) const { return resource.click_raise; } - inline bool isScreenManaged(void) const { return managed; } - inline bool doShadowFonts(void) const { return resource.shadow_fonts; } - inline bool doAAFonts(void) const { return resource.aa_fonts; } - inline bool doImageDither(void) const { return image_control->doDither(); } - inline bool doOrderedDither(void) const { return resource.ordered_dither; } - inline bool doOpaqueMove(void) const { return resource.opaque_move; } - inline bool doFullMax(void) const { return resource.full_max; } - inline bool doFocusNew(void) const { return resource.focus_new; } - inline bool doFocusLast(void) const { return resource.focus_last; } - inline int getWindowToWindowSnap(void) const - { return resource.snap_to_windows; } - inline int getWindowToEdgeSnap(void) const - { return resource.snap_to_edges; } - inline bool getWindowCornerSnap(void) const - { return resource.window_corner_snap; } - inline bool allowScrollLock(void) const { return resource.allow_scroll_lock; } - inline bool doWorkspaceWarping(void) const - { return resource.workspace_warping; } - inline int rootScrollDirection(void) const { return resource.root_scroll; } - - inline const GC &getOpGC(void) const { return opGC; } - - inline Blackbox *getBlackbox(void) { return blackbox; } - inline otk::BColor *getBorderColor(void) { - return &resource.wstyle.border_color; - } - inline otk::BImageControl *getImageControl(void) { return image_control; } - - Workspace *getWorkspace(unsigned int index) const; - - inline Workspace *getCurrentWorkspace(void) { return current_workspace; } - - inline unsigned int getResizeZones(void) const - { return resource.resize_zones; } - inline bool getPlaceIgnoreShaded(void) const - { return resource.ignore_shaded; } - inline bool getPlaceIgnoreMaximized(void) const - { return resource.ignore_maximized; } - - inline unsigned int getCurrentWorkspaceID(void) const - { return current_workspace->getID(); } - inline unsigned int getWorkspaceCount(void) const - { return workspacesList.size(); } - inline unsigned int getIconCount(void) const { return iconList.size(); } - inline unsigned int getNumberOfWorkspaces(void) const - { return resource.workspaces; } - inline int getPlacementPolicy(void) const - { return resource.placement_policy; } - inline int getSnapOffset(void) const - { return resource.snap_offset; } - inline int getSnapThreshold(void) const - { return resource.snap_threshold; } - inline int getResistanceSize(void) const - { return resource.resistance_size; } - inline int getRowPlacementDirection(void) const - { return resource.row_direction; } - inline int getColPlacementDirection(void) const - { return resource.col_direction; } - - void changeWorkspaceCount(unsigned int new_count); - - inline void setRootColormapInstalled(bool r) { root_colormap_installed = r; } - void saveSloppyFocus(bool s); - void saveAutoRaise(bool a); - void saveClickRaise(bool c); - void saveWorkspaces(unsigned int w); - void savePlacementPolicy(int p); - void saveRowPlacementDirection(int d); - void saveColPlacementDirection(int d); - void saveSnapThreshold(int t); - void saveSnapOffset(int o); - void saveResistanceSize(int s); - void saveImageDither(bool d); - void saveShadowFonts(bool f); - void saveAAFonts(bool f); - void saveOpaqueMove(bool o); - void saveFullMax(bool f); - void saveFocusNew(bool f); - void saveFocusLast(bool f); - void saveWindowToEdgeSnap(int s); - void saveWindowToWindowSnap(int s); - void saveWindowCornerSnap(bool s); - void saveResizeZones(unsigned int z); - void savePlaceIgnoreShaded(bool i); - void savePlaceIgnoreMaximized(bool i); - void saveAllowScrollLock(bool a); - void saveWorkspaceWarping(bool w); - void saveRootScrollDirection(int d); - - inline const char *getStrftimeFormat(void) - { return resource.strftime_format.c_str(); } - void saveStrftimeFormat(const std::string& format); - - inline otk::Style *getWindowStyle(void) { return &resource.wstyle; } - - BlackboxWindow *getIcon(unsigned int index); - - // allAvailableAreas should be used whenever possible instead of this function - // as then Xinerama will work correctly. - const otk::Rect& availableArea(void) const; -#ifdef XINERAMA - const RectList& allAvailableAreas(void) const; -#endif // XINERAMA - void updateAvailableArea(void); - void addStrut(otk::Strut *strut); - void removeStrut(otk::Strut *strut); - - unsigned int addWorkspace(void); - unsigned int removeLastWorkspace(void); - void changeWorkspaceID(unsigned int id); - void saveWorkspaceNames(void); - - void addSystrayWindow(Window window); - void removeSystrayWindow(Window window); - - void addIcon(BlackboxWindow *w); - void removeIcon(BlackboxWindow *w); - - void updateClientList(void); - void updateStackingList(void); - void manageWindow(Window w); - void unmanageWindow(BlackboxWindow *w, bool remap); - void raiseWindows(Window *workspace_stack, unsigned int num); - void lowerWindows(Window *workspace_stack, unsigned int num); - void reassociateWindow(BlackboxWindow *w, unsigned int wkspc_id, - bool ignore_sticky); - void propagateWindowName(const BlackboxWindow *bw); - void prevFocus(void) const; - void nextFocus(void) const; - void raiseFocus(void) const; - void load_rc(void); - void save_rc(void); - void reconfigure(void); - void toggleFocusModel(FocusModel model); - void shutdown(void); - void showPosition(int x, int y); - void showGeometry(unsigned int gx, unsigned int gy); - void hideGeometry(void); - - void buttonPressEvent(const XButtonEvent *xbutton); - void propertyNotifyEvent(const XPropertyEvent *pe); -}; - -} - -#endif // __Screen_hh diff --git a/src/workspace.cc b/src/workspace.cc index 2bf9d29a..467d8684 100644 --- a/src/workspace.cc +++ b/src/workspace.cc @@ -27,7 +27,7 @@ using std::string; #include "blackbox.hh" #include "otk/font.hh" #include "otk/display.hh" -#include "screen.hh" +#include "bbscreen.hh" #include "otk/util.hh" #include "bbwindow.hh" #include "workspace.hh" diff --git a/src/xeventhandler.cc b/src/xeventhandler.cc index 9d738dde..afa5ecee 100644 --- a/src/xeventhandler.cc +++ b/src/xeventhandler.cc @@ -13,7 +13,7 @@ // XXX: REMOVE THIS SOON!!#! #include "blackbox.hh" -#include "screen.hh" +#include "bbscreen.hh" extern "C" { #include -- cgit v1.2.3