Xinerama and XRandR dual head support for cwm(1). Now we detect the xrandr
reconfiguration events and change our sizes depending on that. We also detect the xinerama screens for maximize, vertmaximize and initial window placement. This could be improved by automatically resizing maximized windows when the screen resolution changes and by moving windows that would be hidden into visible space. Said changes will come shortly. Tested by many. matthieu@ didn't oppose.
This commit is contained in:
parent
2a4cf94896
commit
eb02c0fb7a
@ -1,4 +1,4 @@
|
|||||||
# $OpenBSD: Makefile,v 1.11 2008/09/22 14:28:04 oga Exp $
|
# $OpenBSD: Makefile,v 1.12 2008/09/29 23:16:46 oga Exp $
|
||||||
|
|
||||||
.include <bsd.xconf.mk>
|
.include <bsd.xconf.mk>
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ SRCS= calmwm.c screen.c xmalloc.c client.c grab.c menu.c \
|
|||||||
CPPFLAGS+= -I${X11BASE}/include -I${X11BASE}/include/freetype2 -I${.CURDIR}
|
CPPFLAGS+= -I${X11BASE}/include -I${X11BASE}/include/freetype2 -I${.CURDIR}
|
||||||
|
|
||||||
LDADD+= -L${X11BASE}/lib -lXft -lXrender -lX11 -lXau -lXdmcp -lXext \
|
LDADD+= -L${X11BASE}/lib -lXft -lXrender -lX11 -lXau -lXdmcp -lXext \
|
||||||
-lfontconfig -lexpat -lfreetype -lz
|
-lfontconfig -lexpat -lfreetype -lz -lXinerama -lXrandr
|
||||||
|
|
||||||
MANDIR= ${X11BASE}/man/cat
|
MANDIR= ${X11BASE}/man/cat
|
||||||
MAN= cwm.1 cwmrc.5
|
MAN= cwm.1 cwmrc.5
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*
|
*
|
||||||
* $Id: calmwm.c,v 1.29 2008/09/22 14:28:04 oga Exp $
|
* $Id: calmwm.c,v 1.30 2008/09/29 23:16:46 oga Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
@ -36,6 +36,7 @@ u_int Nscreens;
|
|||||||
struct client_ctx_q Clientq;
|
struct client_ctx_q Clientq;
|
||||||
|
|
||||||
int Doshape, Shape_ev;
|
int Doshape, Shape_ev;
|
||||||
|
int HasXinerama, HasRandr, Randr_ev;
|
||||||
int Starting;
|
int Starting;
|
||||||
struct conf Conf;
|
struct conf Conf;
|
||||||
|
|
||||||
@ -121,6 +122,8 @@ dpy_init(const char *dpyname)
|
|||||||
|
|
||||||
Doshape = XShapeQueryExtension(X_Dpy, &Shape_ev, &i);
|
Doshape = XShapeQueryExtension(X_Dpy, &Shape_ev, &i);
|
||||||
|
|
||||||
|
HasRandr = XRRQueryExtension(X_Dpy, &Randr_ev, &i);
|
||||||
|
|
||||||
TAILQ_INIT(&Screenq);
|
TAILQ_INIT(&Screenq);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +136,7 @@ x_setup(void)
|
|||||||
|
|
||||||
Nscreens = ScreenCount(X_Dpy);
|
Nscreens = ScreenCount(X_Dpy);
|
||||||
for (i = 0; i < (int)Nscreens; i++) {
|
for (i = 0; i < (int)Nscreens; i++) {
|
||||||
XMALLOC(sc, struct screen_ctx);
|
XCALLOC(sc, struct screen_ctx);
|
||||||
x_setupscreen(sc, i);
|
x_setupscreen(sc, i);
|
||||||
TAILQ_INSERT_TAIL(&Screenq, sc, entry);
|
TAILQ_INSERT_TAIL(&Screenq, sc, entry);
|
||||||
}
|
}
|
||||||
@ -161,6 +164,7 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
|
|||||||
Window *wins, w0, w1;
|
Window *wins, w0, w1;
|
||||||
XWindowAttributes winattr;
|
XWindowAttributes winattr;
|
||||||
XSetWindowAttributes rootattr;
|
XSetWindowAttributes rootattr;
|
||||||
|
int fake;
|
||||||
u_int nwins, i;
|
u_int nwins, i;
|
||||||
|
|
||||||
Curscreen = sc;
|
Curscreen = sc;
|
||||||
@ -246,6 +250,18 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
|
|||||||
XChangeWindowAttributes(X_Dpy, sc->rootwin,
|
XChangeWindowAttributes(X_Dpy, sc->rootwin,
|
||||||
CWEventMask, &rootattr);
|
CWEventMask, &rootattr);
|
||||||
|
|
||||||
|
if (XineramaQueryExtension(X_Dpy, &fake, &fake) == 1 &&
|
||||||
|
((HasXinerama = XineramaIsActive(X_Dpy)) == 1))
|
||||||
|
HasXinerama = 1;
|
||||||
|
if (HasRandr)
|
||||||
|
XRRSelectInput(X_Dpy, sc->rootwin, RRScreenChangeNotifyMask);
|
||||||
|
/*
|
||||||
|
* initial setup of xinerama screens, if we're using RandR then we'll
|
||||||
|
* redo this whenever the screen changes since a CTRC may have been
|
||||||
|
* added or removed
|
||||||
|
*/
|
||||||
|
screen_init_xinerama(sc);
|
||||||
|
|
||||||
XSync(X_Dpy, False);
|
XSync(X_Dpy, False);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*
|
*
|
||||||
* $Id: calmwm.h,v 1.67 2008/09/22 14:28:04 oga Exp $
|
* $Id: calmwm.h,v 1.68 2008/09/29 23:16:46 oga Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CALMWM_H_
|
#ifndef _CALMWM_H_
|
||||||
@ -62,6 +62,9 @@ struct screen_ctx {
|
|||||||
|
|
||||||
XftDraw *xftdraw;
|
XftDraw *xftdraw;
|
||||||
XftColor xftcolor;
|
XftColor xftcolor;
|
||||||
|
|
||||||
|
int xinerama_no;
|
||||||
|
XineramaScreenInfo *xinerama;
|
||||||
};
|
};
|
||||||
|
|
||||||
TAILQ_HEAD(screen_ctx_q, screen_ctx);
|
TAILQ_HEAD(screen_ctx_q, screen_ctx);
|
||||||
@ -369,6 +372,7 @@ void xev_handle_keyrelease(struct xevent *, XEvent *);
|
|||||||
void xev_handle_expose(struct xevent *, XEvent *);
|
void xev_handle_expose(struct xevent *, XEvent *);
|
||||||
void xev_handle_clientmessage(struct xevent *, XEvent *);
|
void xev_handle_clientmessage(struct xevent *, XEvent *);
|
||||||
void xev_handle_shape(struct xevent *, XEvent *);
|
void xev_handle_shape(struct xevent *, XEvent *);
|
||||||
|
void xev_handle_randr(struct xevent *, XEvent *);
|
||||||
void xev_handle_mapping(struct xevent *, XEvent *);
|
void xev_handle_mapping(struct xevent *, XEvent *);
|
||||||
|
|
||||||
#define XEV_QUICK(a, b, c, d, e) do { \
|
#define XEV_QUICK(a, b, c, d, e) do { \
|
||||||
@ -417,6 +421,7 @@ char *xstrdup(const char *);
|
|||||||
struct screen_ctx *screen_fromroot(Window);
|
struct screen_ctx *screen_fromroot(Window);
|
||||||
struct screen_ctx *screen_current(void);
|
struct screen_ctx *screen_current(void);
|
||||||
void screen_updatestackingorder(void);
|
void screen_updatestackingorder(void);
|
||||||
|
void screen_init_xinerama(struct screen_ctx *);
|
||||||
|
|
||||||
void conf_setup(struct conf *, const char *);
|
void conf_setup(struct conf *, const char *);
|
||||||
void conf_client(struct client_ctx *);
|
void conf_client(struct client_ctx *);
|
||||||
@ -512,6 +517,8 @@ extern u_int Nscreens;
|
|||||||
extern struct client_ctx_q Clientq;
|
extern struct client_ctx_q Clientq;
|
||||||
|
|
||||||
extern int Doshape, Shape_ev;
|
extern int Doshape, Shape_ev;
|
||||||
|
extern int Doshape, Shape_ev;
|
||||||
|
extern int HasXinerama, HasRandr, Randr_ev;
|
||||||
extern struct conf Conf;
|
extern struct conf Conf;
|
||||||
|
|
||||||
#endif /* _CALMWM_H_ */
|
#endif /* _CALMWM_H_ */
|
||||||
|
133
app/cwm/client.c
133
app/cwm/client.c
@ -15,13 +15,15 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*
|
*
|
||||||
* $Id: client.c,v 1.40 2008/09/22 14:28:04 oga Exp $
|
* $Id: client.c,v 1.41 2008/09/29 23:16:46 oga Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
|
|
||||||
int _inwindowbounds(struct client_ctx *, int, int);
|
int _inwindowbounds(struct client_ctx *, int, int);
|
||||||
|
XineramaScreenInfo *client_find_xinerama_screen(int , int ,
|
||||||
|
struct screen_ctx *);
|
||||||
|
|
||||||
static char emptystring[] = "";
|
static char emptystring[] = "";
|
||||||
|
|
||||||
@ -322,16 +324,36 @@ void
|
|||||||
client_maximize(struct client_ctx *cc)
|
client_maximize(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc = CCTOSC(cc);
|
struct screen_ctx *sc = CCTOSC(cc);
|
||||||
|
int xmax = sc->xmax, ymax = sc->ymax;
|
||||||
|
int x_org = 0, y_org = 0;
|
||||||
|
|
||||||
if (cc->flags & CLIENT_MAXIMIZED) {
|
if (cc->flags & CLIENT_MAXIMIZED) {
|
||||||
cc->geom = cc->savegeom;
|
cc->geom = cc->savegeom;
|
||||||
} else {
|
} else {
|
||||||
if (!(cc->flags & CLIENT_VMAXIMIZED))
|
if (!(cc->flags & CLIENT_VMAXIMIZED))
|
||||||
cc->savegeom = cc->geom;
|
cc->savegeom = cc->geom;
|
||||||
cc->geom.x = Conf.gap_left;
|
if (HasXinerama) {
|
||||||
cc->geom.y = Conf.gap_top;
|
XineramaScreenInfo *xine;
|
||||||
cc->geom.height = sc->ymax - (Conf.gap_top + Conf.gap_bottom);
|
/*
|
||||||
cc->geom.width = sc->xmax - (Conf.gap_left + Conf.gap_right);
|
* pick screen that the middle of the window is on.
|
||||||
|
* that's probably more fair than if just the origin of
|
||||||
|
* a window is poking over a boundary
|
||||||
|
*/
|
||||||
|
xine = client_find_xinerama_screen(cc->geom.x +
|
||||||
|
cc->geom.width / 2, cc->geom.y +
|
||||||
|
cc->geom.height / 2, CCTOSC(cc));
|
||||||
|
if (xine == NULL)
|
||||||
|
goto calc;
|
||||||
|
x_org = xine->x_org;
|
||||||
|
y_org = xine->y_org;
|
||||||
|
xmax = xine->width;
|
||||||
|
ymax = xine->height;
|
||||||
|
}
|
||||||
|
calc:
|
||||||
|
cc->geom.x = x_org + Conf.gap_left;
|
||||||
|
cc->geom.y = y_org + Conf.gap_top;
|
||||||
|
cc->geom.height = ymax - (Conf.gap_top + Conf.gap_bottom);
|
||||||
|
cc->geom.width = xmax - (Conf.gap_left + Conf.gap_right);
|
||||||
cc->flags |= CLIENT_DOMAXIMIZE;
|
cc->flags |= CLIENT_DOMAXIMIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,15 +364,27 @@ void
|
|||||||
client_vertmaximize(struct client_ctx *cc)
|
client_vertmaximize(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc = CCTOSC(cc);
|
struct screen_ctx *sc = CCTOSC(cc);
|
||||||
|
int y_org = 0, ymax = sc->ymax;
|
||||||
|
|
||||||
if (cc->flags & CLIENT_VMAXIMIZED) {
|
if (cc->flags & CLIENT_VMAXIMIZED) {
|
||||||
cc->geom = cc->savegeom;
|
cc->geom = cc->savegeom;
|
||||||
} else {
|
} else {
|
||||||
if (!(cc->flags & CLIENT_MAXIMIZED))
|
if (!(cc->flags & CLIENT_MAXIMIZED))
|
||||||
cc->savegeom = cc->geom;
|
cc->savegeom = cc->geom;
|
||||||
cc->geom.y = cc->bwidth + Conf.gap_top;
|
if (HasXinerama) {
|
||||||
cc->geom.height = (sc->ymax - cc->bwidth * 2) -
|
XineramaScreenInfo *xine;
|
||||||
(Conf.gap_top + Conf.gap_bottom);
|
xine = client_find_xinerama_screen(cc->geom.x +
|
||||||
|
cc->geom.width / 2, cc->geom.y +
|
||||||
|
cc->geom.height / 2, CCTOSC(cc));
|
||||||
|
if (xine == NULL)
|
||||||
|
goto calc;
|
||||||
|
y_org = xine->y_org;
|
||||||
|
ymax = xine->height;
|
||||||
|
}
|
||||||
|
calc:
|
||||||
|
cc->geom.y = y_org + cc->bwidth + Conf.gap_top;
|
||||||
|
cc->geom.height = ymax - (cc->bwidth * 2) - (Conf.gap_top +
|
||||||
|
Conf.gap_bottom);
|
||||||
cc->flags |= CLIENT_DOVMAXIMIZE;
|
cc->flags |= CLIENT_DOVMAXIMIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,20 +701,18 @@ void
|
|||||||
client_placecalc(struct client_ctx *cc)
|
client_placecalc(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc = CCTOSC(cc);
|
struct screen_ctx *sc = CCTOSC(cc);
|
||||||
int yslack, xslack, xmouse, ymouse;
|
int yslack, xslack;
|
||||||
|
|
||||||
yslack = sc->ymax - cc->geom.height - cc->bwidth;
|
|
||||||
xslack = sc->xmax - cc->geom.width - cc->bwidth;
|
|
||||||
|
|
||||||
xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse);
|
|
||||||
|
|
||||||
xmouse = MAX(xmouse, cc->bwidth) - cc->geom.width / 2;
|
|
||||||
ymouse = MAX(ymouse, cc->bwidth) - cc->geom.height / 2;
|
|
||||||
|
|
||||||
xmouse = MAX(xmouse, (int)cc->bwidth);
|
|
||||||
ymouse = MAX(ymouse, (int)cc->bwidth);
|
|
||||||
|
|
||||||
if (cc->size->flags & USPosition) {
|
if (cc->size->flags & USPosition) {
|
||||||
|
/*
|
||||||
|
* Ignore XINERAMA screens, just make sure it's somewhere
|
||||||
|
* in the virtual desktop. else it stops people putting xterms
|
||||||
|
* at startup in the screen the mouse doesn't start in *sigh*.
|
||||||
|
* XRandR bits mean that {x,y}max shouldn't be outside what's
|
||||||
|
* currently there.
|
||||||
|
*/
|
||||||
|
yslack = sc->ymax - cc->geom.height - cc->bwidth;
|
||||||
|
xslack = sc->xmax - cc->geom.width - cc->bwidth;
|
||||||
if (cc->size->x >= 0)
|
if (cc->size->x >= 0)
|
||||||
cc->geom.x = MAX(MIN(cc->size->x, xslack), cc->bwidth);
|
cc->geom.x = MAX(MIN(cc->size->x, xslack), cc->bwidth);
|
||||||
else
|
else
|
||||||
@ -690,23 +722,50 @@ client_placecalc(struct client_ctx *cc)
|
|||||||
else
|
else
|
||||||
cc->geom.y = cc->bwidth;
|
cc->geom.y = cc->bwidth;
|
||||||
} else {
|
} else {
|
||||||
if (xslack >= 0) {
|
XineramaScreenInfo *info;
|
||||||
|
int xmouse, ymouse, xorig, yorig;
|
||||||
|
int xmax, ymax;
|
||||||
|
|
||||||
|
xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse);
|
||||||
|
if (HasXinerama) {
|
||||||
|
info = client_find_xinerama_screen(xmouse, ymouse, sc);
|
||||||
|
if (info == NULL)
|
||||||
|
goto noxine;
|
||||||
|
xorig = info->x_org;
|
||||||
|
yorig = info->y_org;
|
||||||
|
xmax = xorig + info->width;
|
||||||
|
ymax = yorig + info->height;
|
||||||
|
} else {
|
||||||
|
noxine:
|
||||||
|
xorig = yorig = 0;
|
||||||
|
xmax = sc->xmax;
|
||||||
|
ymax = sc->ymax;
|
||||||
|
}
|
||||||
|
xmouse = MAX(xmouse, xorig + cc->bwidth) - cc->geom.width / 2;
|
||||||
|
ymouse = MAX(ymouse, yorig + cc->bwidth) - cc->geom.height / 2;
|
||||||
|
|
||||||
|
xmouse = MAX(xmouse, xorig + (int)cc->bwidth);
|
||||||
|
ymouse = MAX(ymouse, yorig + (int)cc->bwidth);
|
||||||
|
|
||||||
|
xslack = xmax - cc->geom.width - cc->bwidth;
|
||||||
|
yslack = ymax - cc->geom.height - cc->bwidth;
|
||||||
|
if (xslack >= xorig) {
|
||||||
cc->geom.x = MAX(MIN(xmouse, xslack),
|
cc->geom.x = MAX(MIN(xmouse, xslack),
|
||||||
Conf.gap_left + cc->bwidth);
|
xorig + Conf.gap_left + cc->bwidth);
|
||||||
if (cc->geom.x > (xslack - Conf.gap_right))
|
if (cc->geom.x > (xslack - Conf.gap_right))
|
||||||
cc->geom.x -= Conf.gap_right;
|
cc->geom.x -= Conf.gap_right;
|
||||||
} else {
|
} else {
|
||||||
cc->geom.x = cc->bwidth + Conf.gap_left;
|
cc->geom.x = xorig + cc->bwidth + Conf.gap_left;
|
||||||
cc->geom.width = sc->xmax - Conf.gap_left;
|
cc->geom.width = xmax - Conf.gap_left;
|
||||||
}
|
}
|
||||||
if (yslack >= 0) {
|
if (yslack >= yorig) {
|
||||||
cc->geom.y = MAX(MIN(ymouse, yslack),
|
cc->geom.y = MAX(MIN(ymouse, yslack),
|
||||||
Conf.gap_top + cc->bwidth);
|
yorig + Conf.gap_top + cc->bwidth);
|
||||||
if (cc->geom.y > (yslack - Conf.gap_bottom))
|
if (cc->geom.y > (yslack - Conf.gap_bottom))
|
||||||
cc->geom.y -= Conf.gap_bottom;
|
cc->geom.y -= Conf.gap_bottom;
|
||||||
} else {
|
} else {
|
||||||
cc->geom.y = cc->bwidth + Conf.gap_top;
|
cc->geom.y = yorig + cc->bwidth + Conf.gap_top;
|
||||||
cc->geom.height = sc->ymax - Conf.gap_top;
|
cc->geom.height = ymax - Conf.gap_top;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -793,3 +852,21 @@ _inwindowbounds(struct client_ctx *cc, int x, int y)
|
|||||||
return (x < cc->geom.width && x >= 0 &&
|
return (x < cc->geom.width && x >= 0 &&
|
||||||
y < cc->geom.height && y >= 0);
|
y < cc->geom.height && y >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find which xinerama screen the coordinates (x,y) is on.
|
||||||
|
*/
|
||||||
|
XineramaScreenInfo *
|
||||||
|
client_find_xinerama_screen(int x, int y, struct screen_ctx *sc)
|
||||||
|
{
|
||||||
|
XineramaScreenInfo *info;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < sc->xinerama_no; i++) {
|
||||||
|
info = &sc->xinerama[i];
|
||||||
|
if (x > info->x_org && x < info->x_org + info->width &&
|
||||||
|
y > info->y_org && y < info->y_org + info->height)
|
||||||
|
return (info);
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*
|
*
|
||||||
* $Id: headers.h,v 1.7 2008/09/22 14:28:04 oga Exp $
|
* $Id: headers.h,v 1.8 2008/09/29 23:16:46 oga Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CALMWM_HEADERS_H_
|
#ifndef _CALMWM_HEADERS_H_
|
||||||
@ -41,6 +41,8 @@
|
|||||||
|
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
#include <X11/extensions/shape.h>
|
#include <X11/extensions/shape.h>
|
||||||
|
#include <X11/extensions/Xinerama.h>
|
||||||
|
#include <X11/extensions/Xrandr.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*
|
*
|
||||||
* $Id: screen.c,v 1.10 2008/09/22 14:28:04 oga Exp $
|
* $Id: screen.c,v 1.11 2008/09/29 23:16:46 oga Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
@ -67,3 +67,28 @@ screen_updatestackingorder(void)
|
|||||||
|
|
||||||
XFree(wins);
|
XFree(wins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
screen_init_xinerama(struct screen_ctx *sc)
|
||||||
|
{
|
||||||
|
XineramaScreenInfo *info;
|
||||||
|
int no, fake;
|
||||||
|
|
||||||
|
if (HasXinerama == 0 || XineramaIsActive(X_Dpy) == 0) {
|
||||||
|
HasXinerama = 0;
|
||||||
|
sc->xinerama_no = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = XineramaQueryScreens(X_Dpy, &no);
|
||||||
|
if (info == NULL) {
|
||||||
|
/*is xinerama is actually off, instead of a malloc failure? */
|
||||||
|
if (sc->xinerama == NULL)
|
||||||
|
HasXinerama = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sc->xinerama != NULL)
|
||||||
|
XFree(sc->xinerama);
|
||||||
|
sc->xinerama = info;
|
||||||
|
sc->xinerama_no = no;
|
||||||
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*
|
*
|
||||||
* $Id: xevents.c,v 1.28 2008/09/22 14:28:04 oga Exp $
|
* $Id: xevents.c,v 1.29 2008/09/29 23:16:46 oga Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -375,6 +375,22 @@ xev_handle_shape(struct xevent *xev, XEvent *ee)
|
|||||||
client_do_shape(cc);
|
client_do_shape(cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xev_handle_randr(struct xevent *xev, XEvent *ee)
|
||||||
|
{
|
||||||
|
XRRScreenChangeNotifyEvent *rev = (XRRScreenChangeNotifyEvent *)ee;
|
||||||
|
struct client_ctx *cc;
|
||||||
|
struct screen_ctx *sc;
|
||||||
|
|
||||||
|
if ((cc = client_find(rev->window)) != NULL) {
|
||||||
|
XRRUpdateConfiguration(ee);
|
||||||
|
sc = CCTOSC(cc);
|
||||||
|
sc->xmax = rev->width;
|
||||||
|
sc->ymax = rev->height;
|
||||||
|
screen_init_xinerama(sc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called when the keymap has changed.
|
* Called when the keymap has changed.
|
||||||
* Ungrab all keys, reload keymap and then regrab
|
* Ungrab all keys, reload keymap and then regrab
|
||||||
@ -525,6 +541,8 @@ xev_loop(void)
|
|||||||
default:
|
default:
|
||||||
if (e.type == Shape_ev)
|
if (e.type == Shape_ev)
|
||||||
xev_handle_shape(xev, &e);
|
xev_handle_shape(xev, &e);
|
||||||
|
else if (e.type == Randr_ev)
|
||||||
|
xev_handle_randr(xev, &e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user