all repos — openbox @ bcb14a3ce94ee4b4cba07de7a297470719390331

openbox fork - make it a bit more like ryudo

acquire and provide Xinerama information for the window manager. now we just gotta use it.
Dana Jansens danakj@orodu.net
commit

bcb14a3ce94ee4b4cba07de7a297470719390331

parent

a0cf45a0ef5f7e2cbf0833f4d8655131912400cc

5 files changed, 129 insertions(+), 2 deletions(-)

jump to
M src/BaseDisplay.ccsrc/BaseDisplay.cc

@@ -35,6 +35,10 @@ #ifdef SHAPE

# include <X11/extensions/shape.h> #endif // SHAPE +#ifdef XINERAMA +# include <X11/extensions/Xinerama.h> +#endif // XINERAMA + #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif // HAVE_FCNTL_H

@@ -231,6 +235,22 @@ &shape.error_basep);

#else // !SHAPE shape.extensions = False; #endif // SHAPE + + xinerama.extensions = False; +#ifdef XINERAMA + if (XineramaQueryExtension(display, &xinerama.event_basep, + &xinerama.error_basep)) { + if (XineramaQueryVersion(display, &xinerama.major, + &xinerama.minor)) { +#ifdef DEBUG + fprintf(stderr, + "BaseDisplay::BaseDisplay: Found Xinerama version %d.%d\n", + xinerama.major, xinerama.minor); +#endif // DEBUG + xinerama.extensions = True; + } + } +#endif // XINERAMA XSetErrorHandler((XErrorHandler) handleXErrors);

@@ -462,4 +482,34 @@ default_string.resize(pos);

display_string = string("DISPLAY=") + default_string + '.' + itostring(static_cast<unsigned long>(screen_number)); + +#ifdef XINERAMA + if (d->hasXineramaExtensions()) { + if (d->getXineramaMajorVersion() == 1) { + // we know the version 1(.1?) protocol + + /* + in this version of Xinerama, we can't query on a per-screen basis, but + in future versions we should be able, so the 'activeness' is checked + on a pre-screen basis anyways. + */ + xinerama_active = XineramaIsActive(d->getXDisplay()); + /* + If Xinerama is being used, there there is only going to be one screen + present. We still, of course, want to use the screen class, but that is + why no screen number is used in this function call. There should never + be more than one screen present with Xinerama active. + */ + int num; + XineramaScreenInfo *info = XineramaQueryScreens(d->getXDisplay(), &num); + if (num > 0 && info) { + for (int i = 0; i < num; ++i) { + xinerama_areas.push_back(Rect(info[i].x_org, info[i].y_org, + info[i].width, info[i].height)); + } + XFree(info); + } + } + } +#endif // XINERAMA }
M src/BaseDisplay.hhsrc/BaseDisplay.hh

@@ -50,6 +50,10 @@ int depth;

unsigned int screen_number; std::string display_string; Rect rect; +#ifdef XINERAMA + RectList xinerama_areas; + bool xinerama_active; +#endif public: ScreenInfo(BaseDisplay *d, unsigned int num);

@@ -66,6 +70,10 @@ inline unsigned int getWidth(void) const { return rect.width(); }

inline unsigned int getHeight(void) const { return rect.height(); } inline const std::string& displayString(void) const { return display_string; } +#ifdef XINERAMA + inline const RectList &getXineramaAreas(void) const { return xinerama_areas; } + inline bool isXineramaActive(void) const { return xinerama_active; } +#endif };

@@ -77,6 +85,15 @@ int event_basep, error_basep;

}; BShape shape; +#ifdef XINERAMA + struct BXinerama { + bool extensions; + int event_basep, error_basep; + int major, minor; // version + }; + BXinerama xinerama; +#endif // XINERAMA + unsigned int MaskList[8]; size_t MaskListLength;

@@ -114,6 +131,10 @@ BGCCache *gcCache(void) const;

inline bool hasShapeExtensions(void) const { return shape.extensions; } +#ifdef XINERAMA + inline bool hasXineramaExtensions(void) const + { return xinerama.extensions; } +#endif // XINERAMA inline bool doShutdown(void) const { return run_state == SHUTDOWN; } inline bool isStartup(void) const

@@ -130,6 +151,10 @@ inline unsigned int getNumberOfScreens(void) const

{ return screenInfoList.size(); } inline int getShapeEventBase(void) const { return shape.event_basep; } +#ifdef XINERAMA + inline int getXineramaMajorVersion(void) const + { return xinerama.major; } +#endif // XINERAMA inline void shutdown(void) { run_state = SHUTDOWN; } inline void run(void) { run_state = RUNNING; }
M src/Screen.ccsrc/Screen.cc

@@ -29,6 +29,11 @@ extern "C" {

#include <X11/Xatom.h> #include <X11/keysym.h> +#ifdef XINERAMA +# include <X11/Xlib.h> +# include <X11/extensions/Xinerama.h> +#endif // XINERAMA + #ifdef HAVE_STDLIB_H # include <stdlib.h> #endif // HAVE_STDLIB_H

@@ -154,8 +159,7 @@

XDefineCursor(blackbox->getXDisplay(), getRootWindow(), blackbox->getSessionCursor()); - // start off full screen, top left. - usableArea.setSize(getWidth(), getHeight()); + updateAvailableArea(); image_control = new BImageControl(blackbox, this, True, blackbox->getColorsPerChannel(),

@@ -2070,9 +2074,27 @@ return usableArea;

} +RectList BScreen::allAvailableAreas(void) const { +#ifdef XINERAMA + if (isXineramaActive()) + return xineramaUsableArea; +#endif // XINERAMA + + RectList list; + list.push_back(availableArea()); + return list; +} + + void BScreen::updateAvailableArea(void) { Rect old_area = usableArea; usableArea = getRect(); // reset to full screen + +#ifdef XINERAMA + // reset to the full areas + if (isXineramaActive()) + xineramaUsableArea = allAvailableAreas(); +#endif // XINERAMA /* these values represent offsets from the screen edge * we look for the biggest offset on each edge and then apply them

@@ -2099,6 +2121,27 @@

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(),
M src/Screen.hhsrc/Screen.hh

@@ -131,6 +131,9 @@ unsigned int geom_w, geom_h;

unsigned long event_mask; Rect usableArea; +#ifdef XINERAMA + RectList xineramaUsableArea; +#endif // XINERAMA typedef std::list<Strut*> StrutList; StrutList strutList;

@@ -306,7 +309,10 @@ inline ToolbarStyle *getToolbarStyle(void) { return &resource.tstyle; }

BlackboxWindow *getIcon(unsigned int index); + // allAvailableAreas should be used whenever possible instead of this function + // as then Xinerama will work correctly. const Rect& availableArea(void) const; + RectList allAvailableAreas(void) const; void updateAvailableArea(void); void addStrut(Strut *strut); void removeStrut(Strut *strut);
M src/Util.hhsrc/Util.hh

@@ -28,6 +28,7 @@ #include <X11/Xlib.h>

#include <X11/Xutil.h> #include <string> +#include <list> class Rect { public:

@@ -75,6 +76,8 @@

private: int _x1, _y1, _x2, _y2; }; + +typedef std::list<Rect> RectList; struct Strut { unsigned int top, bottom, left, right;