acquire and provide Xinerama information for the window manager. now we just gotta use it.
This commit is contained in:
parent
a0cf45a0ef
commit
bcb14a3ce9
5 changed files with 129 additions and 2 deletions
|
@ -35,6 +35,10 @@ extern "C" {
|
|||
# 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
|
||||
|
@ -232,6 +236,22 @@ BaseDisplay::BaseDisplay(const char *app_name, const char *dpy_name) {
|
|||
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);
|
||||
|
||||
screenInfoList.reserve(ScreenCount(display));
|
||||
|
@ -462,4 +482,34 @@ ScreenInfo::ScreenInfo(BaseDisplay *d, unsigned int num) {
|
|||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -50,6 +50,10 @@ private:
|
|||
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 @@ public:
|
|||
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 @@ private:
|
|||
};
|
||||
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 @@ public:
|
|||
|
||||
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 @@ public:
|
|||
{ 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; }
|
||||
|
|
|
@ -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 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) {
|
|||
XDefineCursor(blackbox->getXDisplay(), getRootWindow(),
|
||||
blackbox->getSessionCursor());
|
||||
|
||||
// start off full screen, top left.
|
||||
usableArea.setSize(getWidth(), getHeight());
|
||||
updateAvailableArea();
|
||||
|
||||
image_control =
|
||||
new BImageControl(blackbox, this, True, blackbox->getColorsPerChannel(),
|
||||
|
@ -2070,10 +2074,28 @@ const Rect& BScreen::availableArea(void) const {
|
|||
}
|
||||
|
||||
|
||||
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
|
||||
* all at once
|
||||
|
@ -2100,6 +2122,27 @@ void BScreen::updateAvailableArea(void) {
|
|||
usableArea.setSize(usableArea.width() - (current_left + current_right),
|
||||
usableArea.height() - (current_top + current_bottom));
|
||||
|
||||
#ifdef XINERAMA
|
||||
if (isXineramaActive()) {
|
||||
// keep each of the ximerama-defined areas inside the strut
|
||||
RectList::iterator xit, xend = xineramaUsableArea.end();
|
||||
for (xit = xineramaUsableArea.begin(); xit != xend; ++xit) {
|
||||
if (xit->x() < usableArea.x()) {
|
||||
xit->setX(usableArea.x());
|
||||
xit->setWidth(xit->width() - usableArea.x());
|
||||
}
|
||||
if (xit->y() < usableArea.y()) {
|
||||
xit->setY(usableArea.y());
|
||||
xit->setHeight(xit->height() - usableArea.y());
|
||||
}
|
||||
if (xit->x() + xit->width() > usableArea.width())
|
||||
xit->setWidth(usableArea.width() - xit->x());
|
||||
if (xit->y() + xit->height() > usableArea.height())
|
||||
xit->setHeight(usableArea.height() - xit->y());
|
||||
}
|
||||
}
|
||||
#endif // XINERAMA
|
||||
|
||||
if (old_area != usableArea) {
|
||||
BlackboxWindowList::iterator it = windowList.begin(),
|
||||
end = windowList.end();
|
||||
|
|
|
@ -131,6 +131,9 @@ private:
|
|||
unsigned long event_mask;
|
||||
|
||||
Rect usableArea;
|
||||
#ifdef XINERAMA
|
||||
RectList xineramaUsableArea;
|
||||
#endif // XINERAMA
|
||||
|
||||
typedef std::list<Strut*> StrutList;
|
||||
StrutList strutList;
|
||||
|
@ -306,7 +309,10 @@ public:
|
|||
|
||||
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);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <X11/Xutil.h>
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
class Rect {
|
||||
public:
|
||||
|
@ -76,6 +77,8 @@ private:
|
|||
int _x1, _y1, _x2, _y2;
|
||||
};
|
||||
|
||||
typedef std::list<Rect> RectList;
|
||||
|
||||
struct Strut {
|
||||
unsigned int top, bottom, left, right;
|
||||
|
||||
|
|
Loading…
Reference in a new issue