Commit c4a38893 authored by Ulrich Sibiller's avatar Ulrich Sibiller Committed by Mike Gabriel

Xinerama: do not cut off at outer edges

This fixes the problem Mike Gabriel describes like this: - Launch a session on a system with a single monitor. Enable Xinerama for this session. - Open a desktop session in that session window (e.g. MATE or XFCE). - Move the NX/MATE-or-XFCE session window around on that one monitor. Bump at the borders, so that the session window moves into the invisible parts around your monitor. What you see is that the MATE-or-XFCE window manager will become really busy with resizing the windows and panels in the NX session, because moving the window over the physical borders of the display will trigger resize events. This is non-intuitive, I think. Same with multi-monitors on the outside edges of the physical Xorg RandR setup.
parent 4ba8df85
......@@ -180,7 +180,7 @@ INCLUDES = -I. -I$(XBUILDINCDIR) \
# NXAGENT_FONTEXCLUDE Exclude some specific font names (only "-ult1mo" at this moment).
# NXAGENT FULLSCREEN Fullscreen mode
# NXAGENT_RANDR_MODE_PREFIX Use prefixed (i.e., nx_<x>x<y>) RandR modes
#
# NXAGENT_RANDR_XINERAMA_CLIPPING cut off invisible window parts in xinerama mode (you probably do not want this)
#if nxVersion
NX_DEFINES=-DNX_VERSION_CURRENT="$(NX_VERSION_CURRENT)" \
......
......@@ -106,8 +106,8 @@ is" without express or implied warranty.
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#define TEST
#define DEBUG
#undef WATCH
#undef DUMP
......@@ -3640,6 +3640,36 @@ Bool intersect(int ax1, int ay1, unsigned int aw, unsigned int ah,
return TRUE;
}
#ifndef NXAGENT_RANDR_XINERAMA_CLIPPING
/* intersect two rectangles, return aw/ah for w/h if resulting
rectangle is (partly) outside of bounding box */
Bool intersect_bb(int ax1, int ay1, unsigned int aw, unsigned int ah,
int bx1, int by1, unsigned int bw, unsigned int bh,
int bbx1, int bby1, int bbx2, int bby2,
int *x, int *y, unsigned int *w, unsigned int *h)
{
Bool result = intersect(ax1, ay1, aw, ah, bx1, by1, bw, bh, x, y, w, h);
if (result == TRUE) {
/* check if outside of bounding box */
if (ax1 < bbx1 || ax1 + aw > bbx2) {
#ifdef DEBUG
fprintf(stderr, "intersect: box has parts outside bounding box - width stays unchanged [%d]\n", aw);
#endif
*w = aw;
}
if (ay1 < bby1 || ay1 + ah > bby2) {
#ifdef DEBUG
fprintf(stderr, "intersect: box has parts outside bounding box - height stays unchanged [%d]\n", ah);
#endif
*h = ah;
}
}
return result;
}
#endif
int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, int mmHeight)
{
ScreenPtr pScreen;
......@@ -3783,6 +3813,23 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen)
RRGetInfo(pScreen);
#endif
#ifndef NXAGENT_RANDR_XINERAMA_CLIPPING
/* calculate bounding box (outer edges) */
int bbx2, bbx1, bby1, bby2;
bbx2 = bby2 = 0;
bbx1 = bby1 = INT_MAX;
for (i = 0; i < number; i++) {
bbx2 = MAX(bbx2, screeninfo[i].x_org + screeninfo[i].width);
bby2 = MAX(bby2, screeninfo[i].y_org + screeninfo[i].height);
bbx1 = MIN(bbx1, screeninfo[i].x_org);
bby1 = MIN(bby1, screeninfo[i].y_org);
}
#ifdef DEBUG
fprintf(stderr, "nxagentAdjustRandRXinerama: bounding box: left [%d] right [%d] top [%d] bottom[%d]\n", bbx1, bbx2, bby1, bby2);
#endif
#endif
#ifdef DEBUG
fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs [%d], numOutputs [%d]\n", pScrPriv->numCrtcs, pScrPriv->numOutputs);
#endif
......@@ -3873,12 +3920,37 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen)
int new_x, new_y;
unsigned int new_w, new_h;
/*
if ((nxagentOption(X) < bbx1 || (nxagentOption(X) + width >= bbx2 )) {
#ifdef DEBUG
fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: window has parts outside visible area - width stays unchanged [%d]\n", width);
#endif
new_w = width;
}
if ((nxagentOption(Y) < bby1 || (nxagentOption(Y) + height >= bby2 ) {
#ifdef DEBUG
fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: window has parts outside visible area - height stays unchanged [%d]\n", height);
#endif
new_h = height;
}
*/
/* if there's no intersection disconnect the output */
#ifdef NXAGENT_RANDR_XINERAMA_CLIPPING
disable_output = !intersect(nxagentOption(X), nxagentOption(Y),
width, height,
screeninfo[i].x_org, screeninfo[i].y_org,
screeninfo[i].width, screeninfo[i].height,
&new_x, &new_y, &new_w, &new_h);
#else
disable_output = !intersect_bb(nxagentOption(X), nxagentOption(Y),
width, height,
screeninfo[i].x_org, screeninfo[i].y_org,
screeninfo[i].width, screeninfo[i].height,
bbx1, bby1, bbx2, bby2,
&new_x, &new_y, &new_w, &new_h);
#endif
/* save previous mode */
prevmode = pScrPriv->crtcs[i]->mode;
......@@ -3924,6 +3996,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen)
#ifdef DEBUG
fprintf(stderr, "nxagentAdjustRandRXinerama: output %d: intersection is x [%d] y [%d] width [%d] height [%d]\n", i, new_x, new_y, new_w, new_h);
#endif
RROutputSetConnection(pScrPriv->outputs[i], RR_Connected);
memset(&modeInfo, '\0', sizeof(modeInfo));
......@@ -3937,6 +4010,7 @@ int nxagentAdjustRandRXinerama(ScreenPtr pScreen)
#else
sprintf(name, "%dx%d", new_w, new_h);
#endif
modeInfo.width = new_w;
modeInfo.height = new_h;
modeInfo.hTotal = new_w;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment