aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Makefile4
-rw-r--r--calmwm.c20
-rw-r--r--calmwm.h9
-rw-r--r--client.c141
-rw-r--r--headers.h4
-rw-r--r--screen.c27
-rw-r--r--search.c4
-rw-r--r--xevents.c20
8 files changed, 195 insertions, 34 deletions
diff --git a/Makefile b/Makefile
index 11c62da..5e484a1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.9 2008/06/19 02:21:30 oga Exp $
+# $OpenBSD: Makefile,v 1.10 2008/09/22 14:15:03 oga Exp $
.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}
LDADD+= -L${X11BASE}/lib -lXft -lXrender -lX11 -lXau -lXdmcp -lXext \
- -lfontconfig -lexpat -lfreetype -lz
+ -lfontconfig -lexpat -lfreetype -lz -lXinerama -lXrandr
MANDIR= ${X11BASE}/man/cat
MAN= cwm.1 cwmrc.5
diff --git a/calmwm.c b/calmwm.c
index 6508f1d..522e8ce 100644
--- a/calmwm.c
+++ b/calmwm.c
@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: calmwm.c,v 1.27 2008/07/22 21:01:54 oga Exp $
+ * $Id: calmwm.c,v 1.28 2008/09/22 14:15:03 oga Exp $
*/
#include "headers.h"
@@ -36,6 +36,7 @@ u_int Nscreens;
struct client_ctx_q Clientq;
int Doshape, Shape_ev;
+int HasXinerama, HasRandr, Randr_ev;
int Starting;
struct conf Conf;
@@ -121,6 +122,8 @@ dpy_init(const char *dpyname)
Doshape = XShapeQueryExtension(X_Dpy, &Shape_ev, &i);
+ HasRandr = XRRQueryExtension(X_Dpy, &Randr_ev, &i);
+
TAILQ_INIT(&Screenq);
}
@@ -133,7 +136,7 @@ x_setup(void)
Nscreens = ScreenCount(X_Dpy);
for (i = 0; i < (int)Nscreens; i++) {
- XMALLOC(sc, struct screen_ctx);
+ XCALLOC(sc, struct screen_ctx);
x_setupscreen(sc, i);
TAILQ_INSERT_TAIL(&Screenq, sc, entry);
}
@@ -161,6 +164,7 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
Window *wins, w0, w1;
XWindowAttributes winattr;
XSetWindowAttributes rootattr;
+ int fake;
u_int nwins, i;
Curscreen = sc;
@@ -246,6 +250,18 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
XChangeWindowAttributes(X_Dpy, sc->rootwin,
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);
return;
diff --git a/calmwm.h b/calmwm.h
index 4737a19..2deb44e 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: calmwm.h,v 1.65 2008/07/22 21:01:54 oga Exp $
+ * $Id: calmwm.h,v 1.66 2008/09/22 14:15:03 oga Exp $
*/
#ifndef _CALMWM_H_
@@ -62,6 +62,9 @@ struct screen_ctx {
XftDraw *xftdraw;
XftColor xftcolor;
+
+ int xinerama_no;
+ XineramaScreenInfo *xinerama;
};
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_clientmessage(struct xevent *, XEvent *);
void xev_handle_shape(struct xevent *, XEvent *);
+void xev_handle_randr(struct xevent *, XEvent *);
void xev_handle_mapping(struct xevent *, XEvent *);
#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_current(void);
void screen_updatestackingorder(void);
+void screen_init_xinerama(struct screen_ctx *);
void conf_setup(struct conf *, const char *);
void conf_client(struct client_ctx *);
@@ -512,6 +517,8 @@ extern u_int Nscreens;
extern struct client_ctx_q Clientq;
extern int Doshape, Shape_ev;
+extern int Doshape, Shape_ev;
+extern int HasXinerama, HasRandr, Randr_ev;
extern struct conf Conf;
#endif /* _CALMWM_H_ */
diff --git a/client.c b/client.c
index e846697..1daf0d9 100644
--- a/client.c
+++ b/client.c
@@ -15,13 +15,19 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: client.c,v 1.38 2008/07/15 22:12:09 okan Exp $
+ * $Id: client.c,v 1.39 2008/09/22 14:15:03 oga Exp $
*/
#include "headers.h"
#include "calmwm.h"
int _inwindowbounds(struct client_ctx *, int, int);
+static void client_fullmaximize(struct client_ctx *);
+static void client_xinerama_maximize(struct client_ctx *);
+static void client_xinerama_vmax(struct client_ctx *);
+static void client_full_vmax(struct client_ctx *);
+XineramaScreenInfo *client_find_xinerama_screen(int , int ,
+ struct screen_ctx *);
static char emptystring[] = "";
@@ -328,16 +334,42 @@ client_maximize(struct client_ctx *cc)
} else {
if (!(cc->flags & CLIENT_VMAXIMIZED))
cc->savegeom = cc->geom;
- cc->geom.x = Conf.gap_left;
- cc->geom.y = Conf.gap_top;
- cc->geom.height = sc->ymax - (Conf.gap_top + Conf.gap_bottom);
- cc->geom.width = sc->xmax - (Conf.gap_left + Conf.gap_right);
- cc->flags |= CLIENT_DOMAXIMIZE;
+ if (HasXinerama)
+ client_xinerama_maximize(cc);
+ else
+ client_fullmaximize(cc);
}
client_resize(cc);
}
+static void
+client_xinerama_maximize(struct client_ctx *cc)
+{
+ XineramaScreenInfo *xine;
+
+ xine = client_find_xinerama_screen(cc->geom.x, cc->geom.y, CCTOSC(cc));
+ if (xine == NULL)
+ return;
+ cc->geom.x = xine->x_org + Conf.gap_left;
+ cc->geom.y = xine->y_org + Conf.gap_top;
+ cc->geom.height = xine->height - (Conf.gap_top + Conf.gap_bottom);
+ cc->geom.width = xine->width - (Conf.gap_left + Conf.gap_right);
+ cc->flags |= CLIENT_DOMAXIMIZE;
+}
+
+static void
+client_fullmaximize(struct client_ctx *cc)
+{
+ struct screen_ctx *sc = CCTOSC(cc);
+
+ cc->geom.x = Conf.gap_left;
+ cc->geom.y = Conf.gap_top;
+ cc->geom.height = sc->ymax - (Conf.gap_top + Conf.gap_bottom);
+ cc->geom.width = sc->xmax - (Conf.gap_left + Conf.gap_right);
+ cc->flags |= CLIENT_DOMAXIMIZE;
+}
+
void
client_vertmaximize(struct client_ctx *cc)
{
@@ -348,15 +380,40 @@ client_vertmaximize(struct client_ctx *cc)
} else {
if (!(cc->flags & CLIENT_MAXIMIZED))
cc->savegeom = cc->geom;
- cc->geom.y = cc->bwidth + Conf.gap_top;
- cc->geom.height = (sc->ymax - cc->bwidth * 2) -
- (Conf.gap_top + Conf.gap_bottom);
- cc->flags |= CLIENT_DOVMAXIMIZE;
+ if (HasXinerama)
+ client_xinerama_vmax(cc);
+ else
+ client_full_vmax(cc);
}
client_resize(cc);
}
+static void
+client_xinerama_vmax(struct client_ctx *cc)
+{
+ XineramaScreenInfo *xine;
+
+ xine = client_find_xinerama_screen(cc->geom.x, cc->geom.y, CCTOSC(cc));
+ if (xine == NULL)
+ return;
+ cc->geom.y = xine->y_org + cc->bwidth + Conf.gap_top;
+ cc->geom.height = xine->height - (cc->bwidth * 2) - (Conf.gap_top +
+ Conf.gap_bottom);
+ cc->flags |= CLIENT_DOVMAXIMIZE;
+}
+
+static void
+client_full_vmax(struct client_ctx *cc)
+{
+ struct screen_ctx *sc = CCTOSC(cc);
+
+ cc->geom.y = cc->bwidth + Conf.gap_top;
+ cc->geom.height = (sc->ymax - cc->bwidth * 2) -
+ (Conf.gap_top + Conf.gap_bottom);
+ cc->flags |= CLIENT_DOVMAXIMIZE;
+}
+
void
client_resize(struct client_ctx *cc)
{
@@ -668,11 +725,32 @@ client_placecalc(struct client_ctx *cc)
{
struct screen_ctx *sc = CCTOSC(cc);
int yslack, xslack, xmouse, ymouse;
+ int xorig, yorig, xmax, ymax;
+ XineramaScreenInfo *info;
- yslack = sc->ymax - cc->geom.height - cc->bwidth;
- xslack = sc->xmax - cc->geom.width - cc->bwidth;
xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse);
+ if (HasXinerama) {
+ info = client_find_xinerama_screen(xmouse, ymouse, sc);
+ if (info == NULL)
+ goto noxine;
+ yslack = info->y_org + info->height - cc->geom.height -
+ cc->bwidth;
+ xslack = info->x_org + info->width - cc->geom.width -
+ cc->bwidth;
+ xorig = info->x_org;
+ yorig = info->y_org;
+ xmax = xorig + info->width;
+ ymax = yorig + info->height;
+ } else {
+noxine:
+ yslack = sc->ymax - cc->geom.height - cc->bwidth;
+ xslack = sc->xmax - cc->geom.width - cc->bwidth;
+ xorig = yorig = 0;
+ xmax = sc->xmax;
+ ymax = sc->ymax;
+ }
+
xmouse = MAX(xmouse, cc->bwidth) - cc->geom.width / 2;
ymouse = MAX(ymouse, cc->bwidth) - cc->geom.height / 2;
@@ -681,32 +759,32 @@ client_placecalc(struct client_ctx *cc)
ymouse = MAX(ymouse, (int)cc->bwidth);
if (cc->size->flags & USPosition) {
- if (cc->size->x >= 0)
+ if (cc->size->x >= xorig)
cc->geom.x = MAX(MIN(cc->size->x, xslack), cc->bwidth);
else
- cc->geom.x = cc->bwidth;
- if (cc->size->y >= 0)
+ cc->geom.x = xorig + cc->bwidth;
+ if (cc->size->y >= yorig)
cc->geom.y = MAX(MIN(cc->size->y, yslack), cc->bwidth);
else
- cc->geom.y = cc->bwidth;
+ cc->geom.y = yorig + cc->bwidth;
} else {
- if (xslack >= 0) {
+ if (xslack >= xorig) {
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))
cc->geom.x -= Conf.gap_right;
} else {
- cc->geom.x = cc->bwidth + Conf.gap_left;
- cc->geom.width = sc->xmax - Conf.gap_left;
+ cc->geom.x = xorig + cc->bwidth + Conf.gap_left;
+ cc->geom.width = xmax - Conf.gap_left;
}
- if (yslack >= 0) {
+ if (yslack >= yorig) {
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))
cc->geom.y -= Conf.gap_bottom;
} else {
- cc->geom.y = cc->bwidth + Conf.gap_top;
- cc->geom.height = sc->ymax - Conf.gap_top;
+ cc->geom.y = yorig + cc->bwidth + Conf.gap_top;
+ cc->geom.height = ymax - Conf.gap_top;
}
}
}
@@ -793,3 +871,18 @@ _inwindowbounds(struct client_ctx *cc, int x, int y)
return (x < cc->geom.width && x >= 0 &&
y < cc->geom.height && y >= 0);
}
+
+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);
+}
diff --git a/headers.h b/headers.h
index 7ed671b..2bbf4cc 100644
--- a/headers.h
+++ b/headers.h
@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: headers.h,v 1.5 2008/04/15 20:24:41 oga Exp $
+ * $Id: headers.h,v 1.6 2008/09/22 14:15:03 oga Exp $
*/
#ifndef _CALMWM_HEADERS_H_
@@ -41,6 +41,8 @@
#include <X11/cursorfont.h>
#include <X11/extensions/shape.h>
+#include <X11/extensions/Xrandr.h>
+#include <X11/extensions/Xinerama.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
diff --git a/screen.c b/screen.c
index 139c451..be4768b 100644
--- a/screen.c
+++ b/screen.c
@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: screen.c,v 1.8 2008/07/22 19:54:57 oga Exp $
+ * $Id: screen.c,v 1.9 2008/09/22 14:15:03 oga Exp $
*/
#include "headers.h"
@@ -67,3 +67,28 @@ screen_updatestackingorder(void)
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;
+}
diff --git a/search.c b/search.c
index 62fa1c3..9874e96 100644
--- a/search.c
+++ b/search.c
@@ -14,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: search.c,v 1.13 2008/09/03 04:39:12 canacar Exp $
+ * $Id: search.c,v 1.14 2008/09/22 14:15:03 oga Exp $
*/
#include "headers.h"
@@ -132,7 +132,7 @@ search_print_client(struct menu *mi, int list)
flag = '&';
if (list)
- cc->matchname = TAILQ_FIRST(&cc->nameq)->name;
+ cc->matchname = cc->name;
snprintf(mi->print, sizeof(mi->print), "%c%s", flag, cc->matchname);
diff --git a/xevents.c b/xevents.c
index c28f550..9c7ba97 100644
--- a/xevents.c
+++ b/xevents.c
@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: xevents.c,v 1.26 2008/07/22 21:01:54 oga Exp $
+ * $Id: xevents.c,v 1.27 2008/09/22 14:15:03 oga Exp $
*/
/*
@@ -375,6 +375,22 @@ xev_handle_shape(struct xevent *xev, XEvent *ee)
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.
* Ungrab all keys, reload keymap and then regrab
@@ -525,6 +541,8 @@ xev_loop(void)
default:
if (e.type == Shape_ev)
xev_handle_shape(xev, &e);
+ else if (e.type == Randr_ev)
+ xev_handle_randr(xev, &e);
break;
}