mirror of
https://github.com/leahneukirchen/cwm.git
synced 2023-08-10 21:13:12 +03:00
Compare commits
27 Commits
v5.1
...
OPENBSD_5_
Author | SHA1 | Date | |
---|---|---|---|
013497c79c | |||
3f956098d9 | |||
57af364a21 | |||
e42d1c7f01 | |||
0e8815dfb0 | |||
186a78ff1e | |||
cc08aef0df | |||
2450e309ea | |||
6faef40c55 | |||
c8a17ef536 | |||
cb893d0aa9 | |||
315f25f7ab | |||
1124ee5cc1 | |||
287a5b2aad | |||
3681b26914 | |||
8c7964468f | |||
f98e123bfc | |||
956c47dbeb | |||
490ef6a7df | |||
b4d582c6ef | |||
ac82403a51 | |||
dd5bfdb064 | |||
57766d8606 | |||
fb4936d0f7 | |||
63b59e44c1 | |||
1d8839e8ad | |||
26c391b3dd |
47
Makefile
47
Makefile
@ -1,47 +1,24 @@
|
|||||||
# cwm makefile for BSD make and GNU make
|
# $OpenBSD$
|
||||||
# uses pkg-config, DESTDIR and PREFIX
|
|
||||||
|
.include <bsd.xconf.mk>
|
||||||
|
|
||||||
PROG= cwm
|
PROG= cwm
|
||||||
|
|
||||||
PREFIX= /usr/local
|
|
||||||
|
|
||||||
SRCS= calmwm.c screen.c xmalloc.c client.c menu.c \
|
SRCS= calmwm.c screen.c xmalloc.c client.c menu.c \
|
||||||
search.c util.c xutil.c conf.c xevents.c group.c \
|
search.c util.c xutil.c conf.c xevents.c group.c \
|
||||||
kbfunc.c mousefunc.c font.c parse.y
|
kbfunc.c mousefunc.c font.c parse.y
|
||||||
|
|
||||||
OBJS= calmwm.o screen.o xmalloc.o client.o menu.o \
|
CPPFLAGS+= -I${X11BASE}/include -I${X11BASE}/include/freetype2 -I${.CURDIR}
|
||||||
search.o util.o xutil.o conf.o xevents.o group.o \
|
|
||||||
kbfunc.o mousefunc.o font.o strlcpy.o strlcat.o y.tab.o \
|
|
||||||
strtonum.o fgetln.o
|
|
||||||
|
|
||||||
CPPFLAGS+= `pkg-config --cflags fontconfig x11 xft xinerama xrandr`
|
CFLAGS+= -Wall
|
||||||
|
|
||||||
CFLAGS= -Wall -O2 -g
|
LDADD+= -L${X11BASE}/lib -lXft -lXrender -lX11 -lxcb -lXau -lXdmcp \
|
||||||
|
-lfontconfig -lexpat -lfreetype -lz -lXinerama -lXrandr -lXext
|
||||||
|
|
||||||
LDFLAGS+= `pkg-config --libs fontconfig x11 xft xinerama xrandr`
|
MANDIR= ${X11BASE}/man/man
|
||||||
|
MAN= cwm.1 cwmrc.5
|
||||||
|
|
||||||
MANPREFIX= ${PREFIX}/share/man
|
obj: _xenocara_obj
|
||||||
|
|
||||||
all: ${PROG}
|
.include <bsd.prog.mk>
|
||||||
|
.include <bsd.xorg.mk>
|
||||||
clean:
|
|
||||||
rm -rf ${OBJS} ${PROG} y.tab.c
|
|
||||||
|
|
||||||
y.tab.c: parse.y
|
|
||||||
yacc parse.y
|
|
||||||
|
|
||||||
${PROG}: ${OBJS} y.tab.o
|
|
||||||
${CC} ${OBJS} ${LDFLAGS} -o ${PROG}
|
|
||||||
|
|
||||||
.c.o:
|
|
||||||
${CC} -c ${CFLAGS} ${CPPFLAGS} $<
|
|
||||||
|
|
||||||
install: ${PROG}
|
|
||||||
install -d ${DESTDIR}${PREFIX}/bin ${DESTDIR}${MANPREFIX}/man1 ${DESTDIR}${MANPREFIX}/man5
|
|
||||||
install -m 755 cwm ${DESTDIR}${PREFIX}/bin
|
|
||||||
install -m 644 cwm.1 ${DESTDIR}${MANPREFIX}/man1
|
|
||||||
install -m 644 cwmrc.5 ${DESTDIR}${MANPREFIX}/man5
|
|
||||||
|
|
||||||
release:
|
|
||||||
VERSION=$$(git describe --tags | sed 's/^v//;s/-[^.]*$$//') && \
|
|
||||||
git archive --prefix=cwm-$$VERSION/ -o cwm-$$VERSION.tar.gz HEAD
|
|
||||||
|
24
README
24
README
@ -1,24 +0,0 @@
|
|||||||
This is a port of OpenBSD's excellent cwm[0] to Linux and other
|
|
||||||
Unices.
|
|
||||||
|
|
||||||
cwm is a window manager for X11 which contains many features that
|
|
||||||
concentrate on the efficiency and transparency of window
|
|
||||||
management. cwm also aims to maintain the simplest and most
|
|
||||||
pleasant aesthetic.
|
|
||||||
|
|
||||||
This port requires pkg-config, Xft, Xinerama and Xrandr. The included
|
|
||||||
Makefile should work with both GNU make and BSD make.
|
|
||||||
|
|
||||||
This version actively tracks changes in the OpenBSD CVS repository.
|
|
||||||
Releases are roughly coordinated.
|
|
||||||
|
|
||||||
The revision controlled version is at https://github.com/chneukirchen/cwm
|
|
||||||
Releases can be found at http://chneukirchen.org/releases
|
|
||||||
|
|
||||||
ChangeLog:
|
|
||||||
|
|
||||||
2012-05-02: First public release 5.1 of portable cwm.
|
|
||||||
|
|
||||||
--Christian Neukirchen <chneukirchen@gmail.com>
|
|
||||||
|
|
||||||
[0]: http://www.openbsd.org/cgi-bin/cvsweb/xenocara/app/cwm/
|
|
23
calmwm.c
23
calmwm.c
@ -44,7 +44,7 @@ Cursor Cursor_resize;
|
|||||||
struct screen_ctx_q Screenq = TAILQ_HEAD_INITIALIZER(Screenq);
|
struct screen_ctx_q Screenq = TAILQ_HEAD_INITIALIZER(Screenq);
|
||||||
struct client_ctx_q Clientq = TAILQ_HEAD_INITIALIZER(Clientq);
|
struct client_ctx_q Clientq = TAILQ_HEAD_INITIALIZER(Clientq);
|
||||||
|
|
||||||
int HasXinerama, HasRandr, Randr_ev;
|
int HasRandr, Randr_ev;
|
||||||
struct conf Conf;
|
struct conf Conf;
|
||||||
|
|
||||||
static void sigchld_cb(int);
|
static void sigchld_cb(int);
|
||||||
@ -157,14 +157,17 @@ 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;
|
||||||
|
|
||||||
sc->which = which;
|
sc->which = which;
|
||||||
sc->rootwin = RootWindow(X_Dpy, sc->which);
|
sc->rootwin = RootWindow(X_Dpy, sc->which);
|
||||||
|
|
||||||
|
xu_ewmh_net_supported(sc);
|
||||||
|
xu_ewmh_net_supported_wm_check(sc);
|
||||||
|
|
||||||
conf_gap(&Conf, sc);
|
conf_gap(&Conf, sc);
|
||||||
screen_update_geometry(sc, DisplayWidth(X_Dpy, sc->which),
|
|
||||||
DisplayHeight(X_Dpy, sc->which));
|
screen_update_geometry(sc);
|
||||||
|
|
||||||
conf_color(&Conf, sc);
|
conf_color(&Conf, sc);
|
||||||
|
|
||||||
@ -176,8 +179,6 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
|
|||||||
/* Initialize menu window. */
|
/* Initialize menu window. */
|
||||||
menu_init(sc);
|
menu_init(sc);
|
||||||
|
|
||||||
xu_setwmname(sc);
|
|
||||||
|
|
||||||
rootattr.cursor = Cursor_normal;
|
rootattr.cursor = Cursor_normal;
|
||||||
rootattr.event_mask = CHILDMASK|PropertyChangeMask|EnterWindowMask|
|
rootattr.event_mask = CHILDMASK|PropertyChangeMask|EnterWindowMask|
|
||||||
LeaveWindowMask|ColormapChangeMask|BUTTONMASK;
|
LeaveWindowMask|ColormapChangeMask|BUTTONMASK;
|
||||||
@ -199,17 +200,8 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
|
|||||||
|
|
||||||
screen_updatestackingorder(sc);
|
screen_updatestackingorder(sc);
|
||||||
|
|
||||||
if (XineramaQueryExtension(X_Dpy, &fake, &fake) == 1 &&
|
|
||||||
((HasXinerama = XineramaIsActive(X_Dpy)) == 1))
|
|
||||||
HasXinerama = 1;
|
|
||||||
if (HasRandr)
|
if (HasRandr)
|
||||||
XRRSelectInput(X_Dpy, sc->rootwin, RRScreenChangeNotifyMask);
|
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);
|
||||||
}
|
}
|
||||||
@ -221,6 +213,7 @@ x_wmerrorhandler(Display *dpy, XErrorEvent *e)
|
|||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
x_errorhandler(Display *dpy, XErrorEvent *e)
|
x_errorhandler(Display *dpy, XErrorEvent *e)
|
||||||
{
|
{
|
||||||
|
115
calmwm.h
115
calmwm.h
@ -21,18 +21,7 @@
|
|||||||
#ifndef _CALMWM_H_
|
#ifndef _CALMWM_H_
|
||||||
#define _CALMWM_H_
|
#define _CALMWM_H_
|
||||||
|
|
||||||
/* ugly stuff */
|
#include <X11/XKBlib.h>
|
||||||
#ifndef TAILQ_END
|
|
||||||
#define TAILQ_END(head) NULL
|
|
||||||
#endif
|
|
||||||
#ifndef __dead
|
|
||||||
#define __dead
|
|
||||||
#endif
|
|
||||||
char *fgetln(FILE *, size_t *);
|
|
||||||
long long strtonum(const char *, long long, long long, const char **);
|
|
||||||
size_t strlcpy(char *, const char *, size_t);
|
|
||||||
size_t strlcat(char *, const char *, size_t);
|
|
||||||
|
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <X11/Xft/Xft.h>
|
#include <X11/Xft/Xft.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
@ -107,6 +96,13 @@ struct color {
|
|||||||
unsigned long pixel;
|
unsigned long pixel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct geom {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
};
|
||||||
|
|
||||||
struct gap {
|
struct gap {
|
||||||
int top;
|
int top;
|
||||||
int bottom;
|
int bottom;
|
||||||
@ -129,12 +125,7 @@ struct client_ctx {
|
|||||||
XSizeHints *size;
|
XSizeHints *size;
|
||||||
Colormap cmap;
|
Colormap cmap;
|
||||||
u_int bwidth; /* border width */
|
u_int bwidth; /* border width */
|
||||||
struct {
|
struct geom geom, savegeom;
|
||||||
int x; /* x position */
|
|
||||||
int y; /* y position */
|
|
||||||
int width; /* width */
|
|
||||||
int height;/* height */
|
|
||||||
} geom, savegeom;
|
|
||||||
struct {
|
struct {
|
||||||
int basew; /* desired width */
|
int basew; /* desired width */
|
||||||
int baseh; /* desired height */
|
int baseh; /* desired height */
|
||||||
@ -214,9 +205,9 @@ struct screen_ctx {
|
|||||||
Window menuwin;
|
Window menuwin;
|
||||||
struct color color[CWM_COLOR_MAX];
|
struct color color[CWM_COLOR_MAX];
|
||||||
GC gc;
|
GC gc;
|
||||||
int altpersist;
|
int cycling;
|
||||||
int xmax;
|
struct geom view; /* viewable area */
|
||||||
int ymax;
|
struct geom work; /* workable area, gap-applied */
|
||||||
struct gap gap;
|
struct gap gap;
|
||||||
struct cycle_entry_q mruq;
|
struct cycle_entry_q mruq;
|
||||||
XftColor xftcolor;
|
XftColor xftcolor;
|
||||||
@ -318,6 +309,7 @@ __dead void usage(void);
|
|||||||
void client_applysizehints(struct client_ctx *);
|
void client_applysizehints(struct client_ctx *);
|
||||||
struct client_ctx *client_current(void);
|
struct client_ctx *client_current(void);
|
||||||
void client_cycle(struct screen_ctx *, int);
|
void client_cycle(struct screen_ctx *, int);
|
||||||
|
void client_cycle_leave(struct screen_ctx *, struct client_ctx *);
|
||||||
void client_delete(struct client_ctx *);
|
void client_delete(struct client_ctx *);
|
||||||
void client_draw_border(struct client_ctx *);
|
void client_draw_border(struct client_ctx *);
|
||||||
struct client_ctx *client_find(Window);
|
struct client_ctx *client_find(Window);
|
||||||
@ -370,8 +362,7 @@ void search_print_client(struct menu *, int);
|
|||||||
|
|
||||||
XineramaScreenInfo *screen_find_xinerama(struct screen_ctx *, int, int);
|
XineramaScreenInfo *screen_find_xinerama(struct screen_ctx *, int, int);
|
||||||
struct screen_ctx *screen_fromroot(Window);
|
struct screen_ctx *screen_fromroot(Window);
|
||||||
void screen_init_xinerama(struct screen_ctx *);
|
void screen_update_geometry(struct screen_ctx *);
|
||||||
void screen_update_geometry(struct screen_ctx *, int, int);
|
|
||||||
void screen_updatestackingorder(struct screen_ctx *);
|
void screen_updatestackingorder(struct screen_ctx *);
|
||||||
|
|
||||||
void kbfunc_client_cycle(struct client_ctx *, union arg *);
|
void kbfunc_client_cycle(struct client_ctx *, union arg *);
|
||||||
@ -473,7 +464,22 @@ void xu_ptr_setpos(Window, int, int);
|
|||||||
void xu_ptr_ungrab(void);
|
void xu_ptr_ungrab(void);
|
||||||
void xu_sendmsg(Window, Atom, long);
|
void xu_sendmsg(Window, Atom, long);
|
||||||
void xu_setstate(struct client_ctx *, int);
|
void xu_setstate(struct client_ctx *, int);
|
||||||
void xu_setwmname(struct screen_ctx *);
|
|
||||||
|
void xu_ewmh_net_supported(struct screen_ctx *);
|
||||||
|
void xu_ewmh_net_supported_wm_check(struct screen_ctx *);
|
||||||
|
void xu_ewmh_net_desktop_geometry(struct screen_ctx *);
|
||||||
|
void xu_ewmh_net_workarea(struct screen_ctx *);
|
||||||
|
void xu_ewmh_net_client_list(struct screen_ctx *);
|
||||||
|
void xu_ewmh_net_active_window(struct screen_ctx *, Window);
|
||||||
|
void xu_ewmh_net_wm_desktop_viewport(struct screen_ctx *);
|
||||||
|
void xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *);
|
||||||
|
void xu_ewmh_net_showing_desktop(struct screen_ctx *);
|
||||||
|
void xu_ewmh_net_virtual_roots(struct screen_ctx *);
|
||||||
|
void xu_ewmh_net_current_desktop(struct screen_ctx *, long);
|
||||||
|
void xu_ewmh_net_desktop_names(struct screen_ctx *, unsigned char *, int);
|
||||||
|
|
||||||
|
void xu_ewmh_net_wm_desktop(struct client_ctx *);
|
||||||
|
|
||||||
|
|
||||||
void u_exec(char *);
|
void u_exec(char *);
|
||||||
void u_spawn(char *);
|
void u_spawn(char *);
|
||||||
@ -498,34 +504,37 @@ extern struct conf Conf;
|
|||||||
|
|
||||||
extern int HasXinerama, HasRandr, Randr_ev;
|
extern int HasXinerama, HasRandr, Randr_ev;
|
||||||
|
|
||||||
#define WM_STATE cwm_atoms[0]
|
enum {
|
||||||
#define WM_DELETE_WINDOW cwm_atoms[1]
|
WM_STATE,
|
||||||
#define WM_TAKE_FOCUS cwm_atoms[2]
|
WM_DELETE_WINDOW,
|
||||||
#define WM_PROTOCOLS cwm_atoms[3]
|
WM_TAKE_FOCUS,
|
||||||
#define _MOTIF_WM_HINTS cwm_atoms[4]
|
WM_PROTOCOLS,
|
||||||
#define UTF8_STRING cwm_atoms[5]
|
_MOTIF_WM_HINTS,
|
||||||
/*
|
UTF8_STRING,
|
||||||
* please make all hints below this point netwm hints, starting with
|
CWMH_NITEMS
|
||||||
* _NET_SUPPORTED. If you change other hints make sure you update
|
};
|
||||||
* CWM_NETWM_START
|
enum {
|
||||||
*/
|
_NET_SUPPORTED,
|
||||||
#define _NET_SUPPORTED cwm_atoms[6]
|
_NET_SUPPORTING_WM_CHECK,
|
||||||
#define _NET_SUPPORTING_WM_CHECK cwm_atoms[7]
|
_NET_ACTIVE_WINDOW,
|
||||||
#define _NET_WM_NAME cwm_atoms[8]
|
_NET_CLIENT_LIST,
|
||||||
#define _NET_ACTIVE_WINDOW cwm_atoms[9]
|
_NET_NUMBER_OF_DESKTOPS,
|
||||||
#define _NET_CLIENT_LIST cwm_atoms[10]
|
_NET_CURRENT_DESKTOP,
|
||||||
#define _NET_NUMBER_OF_DESKTOPS cwm_atoms[11]
|
_NET_DESKTOP_VIEWPORT,
|
||||||
#define _NET_CURRENT_DESKTOP cwm_atoms[12]
|
_NET_DESKTOP_GEOMETRY,
|
||||||
#define _NET_DESKTOP_VIEWPORT cwm_atoms[13]
|
_NET_VIRTUAL_ROOTS,
|
||||||
#define _NET_DESKTOP_GEOMETRY cwm_atoms[14]
|
_NET_SHOWING_DESKTOP,
|
||||||
#define _NET_VIRTUAL_ROOTS cwm_atoms[15]
|
_NET_DESKTOP_NAMES,
|
||||||
#define _NET_SHOWING_DESKTOP cwm_atoms[16]
|
_NET_WORKAREA,
|
||||||
#define _NET_DESKTOP_NAMES cwm_atoms[17]
|
_NET_WM_NAME,
|
||||||
#define _NET_WM_DESKTOP cwm_atoms[18]
|
_NET_WM_DESKTOP,
|
||||||
#define _NET_WORKAREA cwm_atoms[19]
|
EWMH_NITEMS
|
||||||
#define CWM_NO_ATOMS 20
|
};
|
||||||
#define CWM_NETWM_START 6
|
struct atom_ctx {
|
||||||
|
char *name;
|
||||||
extern Atom cwm_atoms[CWM_NO_ATOMS];
|
Atom atom;
|
||||||
|
};
|
||||||
|
extern struct atom_ctx cwmh[CWMH_NITEMS];
|
||||||
|
extern struct atom_ctx ewmh[EWMH_NITEMS];
|
||||||
|
|
||||||
#endif /* _CALMWM_H_ */
|
#endif /* _CALMWM_H_ */
|
||||||
|
232
client.c
232
client.c
@ -89,8 +89,8 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
|
|||||||
XGetWindowAttributes(X_Dpy, cc->win, &wattr);
|
XGetWindowAttributes(X_Dpy, cc->win, &wattr);
|
||||||
cc->geom.x = wattr.x;
|
cc->geom.x = wattr.x;
|
||||||
cc->geom.y = wattr.y;
|
cc->geom.y = wattr.y;
|
||||||
cc->geom.width = wattr.width;
|
cc->geom.w = wattr.width;
|
||||||
cc->geom.height = wattr.height;
|
cc->geom.h = wattr.height;
|
||||||
cc->cmap = wattr.colormap;
|
cc->cmap = wattr.colormap;
|
||||||
|
|
||||||
if (wattr.map_state != IsViewable) {
|
if (wattr.map_state != IsViewable) {
|
||||||
@ -126,9 +126,8 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
|
|||||||
|
|
||||||
TAILQ_INSERT_TAIL(&sc->mruq, cc, mru_entry);
|
TAILQ_INSERT_TAIL(&sc->mruq, cc, mru_entry);
|
||||||
TAILQ_INSERT_TAIL(&Clientq, cc, entry);
|
TAILQ_INSERT_TAIL(&Clientq, cc, entry);
|
||||||
/* append to the client list */
|
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, _NET_CLIENT_LIST, XA_WINDOW, 32,
|
xu_ewmh_net_client_list(sc);
|
||||||
PropModeAppend, (unsigned char *)&cc->win, 1);
|
|
||||||
|
|
||||||
client_gethints(cc);
|
client_gethints(cc);
|
||||||
client_update(cc);
|
client_update(cc);
|
||||||
@ -143,10 +142,7 @@ void
|
|||||||
client_delete(struct client_ctx *cc)
|
client_delete(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc = cc->sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
struct client_ctx *tcc;
|
|
||||||
struct winname *wn;
|
struct winname *wn;
|
||||||
Window *winlist;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
group_client_delete(cc);
|
group_client_delete(cc);
|
||||||
|
|
||||||
@ -159,23 +155,8 @@ client_delete(struct client_ctx *cc)
|
|||||||
|
|
||||||
TAILQ_REMOVE(&sc->mruq, cc, mru_entry);
|
TAILQ_REMOVE(&sc->mruq, cc, mru_entry);
|
||||||
TAILQ_REMOVE(&Clientq, cc, entry);
|
TAILQ_REMOVE(&Clientq, cc, entry);
|
||||||
/*
|
|
||||||
* Sadly we can't remove just one entry from a property, so we must
|
xu_ewmh_net_client_list(sc);
|
||||||
* redo the whole thing from scratch. this is the stupid way, the other
|
|
||||||
* way incurs many roundtrips to the server.
|
|
||||||
*/
|
|
||||||
i = j = 0;
|
|
||||||
TAILQ_FOREACH(tcc, &Clientq, entry)
|
|
||||||
i++;
|
|
||||||
if (i > 0) {
|
|
||||||
winlist = xmalloc(i * sizeof(*winlist));
|
|
||||||
TAILQ_FOREACH(tcc, &Clientq, entry)
|
|
||||||
winlist[j++] = tcc->win;
|
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, _NET_CLIENT_LIST,
|
|
||||||
XA_WINDOW, 32, PropModeReplace,
|
|
||||||
(unsigned char *)winlist, i);
|
|
||||||
xfree(winlist);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_curcc == cc)
|
if (_curcc == cc)
|
||||||
client_none(sc);
|
client_none(sc);
|
||||||
@ -228,7 +209,7 @@ client_setactive(struct client_ctx *cc, int fg)
|
|||||||
* If we're in the middle of alt-tabbing, don't change
|
* If we're in the middle of alt-tabbing, don't change
|
||||||
* the order please.
|
* the order please.
|
||||||
*/
|
*/
|
||||||
if (!sc->altpersist)
|
if (!sc->cycling)
|
||||||
client_mtf(cc);
|
client_mtf(cc);
|
||||||
} else
|
} else
|
||||||
client_leave(cc);
|
client_leave(cc);
|
||||||
@ -236,9 +217,7 @@ client_setactive(struct client_ctx *cc, int fg)
|
|||||||
if (fg && _curcc != cc) {
|
if (fg && _curcc != cc) {
|
||||||
client_setactive(NULL, 0);
|
client_setactive(NULL, 0);
|
||||||
_curcc = cc;
|
_curcc = cc;
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, _NET_ACTIVE_WINDOW,
|
xu_ewmh_net_active_window(sc, cc->win);
|
||||||
XA_WINDOW, 32, PropModeReplace,
|
|
||||||
(unsigned char *)&cc->win, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cc->active = fg;
|
cc->active = fg;
|
||||||
@ -253,8 +232,8 @@ client_none(struct screen_ctx *sc)
|
|||||||
{
|
{
|
||||||
Window none = None;
|
Window none = None;
|
||||||
|
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, _NET_ACTIVE_WINDOW,
|
xu_ewmh_net_active_window(sc, none);
|
||||||
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&none, 1);
|
|
||||||
_curcc = NULL;
|
_curcc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,8 +256,8 @@ void
|
|||||||
client_maximize(struct client_ctx *cc)
|
client_maximize(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc = cc->sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
int xmax = sc->xmax, ymax = sc->ymax;
|
int x_org, y_org, xmax, ymax;
|
||||||
int x_org = 0, y_org = 0;
|
XineramaScreenInfo *xine;
|
||||||
|
|
||||||
if (cc->flags & CLIENT_FREEZE)
|
if (cc->flags & CLIENT_FREEZE)
|
||||||
return;
|
return;
|
||||||
@ -291,37 +270,38 @@ client_maximize(struct client_ctx *cc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((cc->flags & CLIENT_VMAXIMIZED) == 0) {
|
if ((cc->flags & CLIENT_VMAXIMIZED) == 0) {
|
||||||
cc->savegeom.height = cc->geom.height;
|
cc->savegeom.h = cc->geom.h;
|
||||||
cc->savegeom.y = cc->geom.y;
|
cc->savegeom.y = cc->geom.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cc->flags & CLIENT_HMAXIMIZED) == 0) {
|
if ((cc->flags & CLIENT_HMAXIMIZED) == 0) {
|
||||||
cc->savegeom.width = cc->geom.width;
|
cc->savegeom.w = cc->geom.w;
|
||||||
cc->savegeom.x = cc->geom.x;
|
cc->savegeom.x = cc->geom.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasXinerama) {
|
|
||||||
XineramaScreenInfo *xine;
|
|
||||||
/*
|
/*
|
||||||
* pick screen that the middle of the window is on.
|
* pick screen that the middle of the window is on.
|
||||||
* that's probably more fair than if just the origin of
|
* that's probably more fair than if just the origin of
|
||||||
* a window is poking over a boundary
|
* a window is poking over a boundary
|
||||||
*/
|
*/
|
||||||
xine = screen_find_xinerama(sc,
|
xine = screen_find_xinerama(sc,
|
||||||
cc->geom.x + cc->geom.width / 2,
|
cc->geom.x + cc->geom.w / 2,
|
||||||
cc->geom.y + cc->geom.height / 2);
|
cc->geom.y + cc->geom.h / 2);
|
||||||
if (xine == NULL)
|
if (xine) {
|
||||||
goto calc;
|
|
||||||
x_org = xine->x_org;
|
x_org = xine->x_org;
|
||||||
y_org = xine->y_org;
|
y_org = xine->y_org;
|
||||||
xmax = xine->width;
|
xmax = xine->width;
|
||||||
ymax = xine->height;
|
ymax = xine->height;
|
||||||
|
} else {
|
||||||
|
x_org = y_org = 0;
|
||||||
|
xmax = sc->view.w;
|
||||||
|
ymax = sc->view.h;
|
||||||
}
|
}
|
||||||
calc:
|
|
||||||
cc->geom.x = x_org + sc->gap.left;
|
cc->geom.x = x_org + sc->gap.left;
|
||||||
cc->geom.y = y_org + sc->gap.top;
|
cc->geom.y = y_org + sc->gap.top;
|
||||||
cc->geom.height = ymax - (sc->gap.top + sc->gap.bottom);
|
cc->geom.h = ymax - (sc->gap.top + sc->gap.bottom);
|
||||||
cc->geom.width = xmax - (sc->gap.left + sc->gap.right);
|
cc->geom.w = xmax - (sc->gap.left + sc->gap.right);
|
||||||
cc->bwidth = 0;
|
cc->bwidth = 0;
|
||||||
cc->flags |= CLIENT_MAXIMIZED;
|
cc->flags |= CLIENT_MAXIMIZED;
|
||||||
|
|
||||||
@ -333,43 +313,44 @@ void
|
|||||||
client_vertmaximize(struct client_ctx *cc)
|
client_vertmaximize(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc = cc->sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
int y_org = 0, ymax = sc->ymax;
|
int y_org, ymax;
|
||||||
|
XineramaScreenInfo *xine;
|
||||||
|
|
||||||
if (cc->flags & CLIENT_FREEZE)
|
if (cc->flags & CLIENT_FREEZE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cc->flags & CLIENT_VMAXIMIZED) {
|
if (cc->flags & CLIENT_VMAXIMIZED) {
|
||||||
cc->geom.y = cc->savegeom.y;
|
cc->geom.y = cc->savegeom.y;
|
||||||
cc->geom.height = cc->savegeom.height;
|
cc->geom.h = cc->savegeom.h;
|
||||||
cc->bwidth = Conf.bwidth;
|
cc->bwidth = Conf.bwidth;
|
||||||
if (cc->flags & CLIENT_HMAXIMIZED)
|
if (cc->flags & CLIENT_HMAXIMIZED)
|
||||||
cc->geom.width -= cc->bwidth * 2;
|
cc->geom.w -= cc->bwidth * 2;
|
||||||
cc->flags &= ~CLIENT_VMAXIMIZED;
|
cc->flags &= ~CLIENT_VMAXIMIZED;
|
||||||
goto resize;
|
goto resize;
|
||||||
}
|
}
|
||||||
|
|
||||||
cc->savegeom.y = cc->geom.y;
|
cc->savegeom.y = cc->geom.y;
|
||||||
cc->savegeom.height = cc->geom.height;
|
cc->savegeom.h = cc->geom.h;
|
||||||
|
|
||||||
/* if this will make us fully maximized then remove boundary */
|
/* if this will make us fully maximized then remove boundary */
|
||||||
if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_HMAXIMIZED) {
|
if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_HMAXIMIZED) {
|
||||||
cc->geom.width += Conf.bwidth * 2;
|
cc->geom.w += Conf.bwidth * 2;
|
||||||
cc->bwidth = 0;
|
cc->bwidth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasXinerama) {
|
|
||||||
XineramaScreenInfo *xine;
|
|
||||||
xine = screen_find_xinerama(sc,
|
xine = screen_find_xinerama(sc,
|
||||||
cc->geom.x + cc->geom.width / 2,
|
cc->geom.x + cc->geom.w / 2,
|
||||||
cc->geom.y + cc->geom.height / 2);
|
cc->geom.y + cc->geom.h / 2);
|
||||||
if (xine == NULL)
|
if (xine) {
|
||||||
goto calc;
|
|
||||||
y_org = xine->y_org;
|
y_org = xine->y_org;
|
||||||
ymax = xine->height;
|
ymax = xine->height;
|
||||||
|
} else {
|
||||||
|
y_org = 0;
|
||||||
|
ymax = sc->view.h;
|
||||||
}
|
}
|
||||||
calc:
|
|
||||||
cc->geom.y = y_org + sc->gap.top;
|
cc->geom.y = y_org + sc->gap.top;
|
||||||
cc->geom.height = ymax - (cc->bwidth * 2) - (sc->gap.top +
|
cc->geom.h = ymax - (cc->bwidth * 2) - (sc->gap.top +
|
||||||
sc->gap.bottom);
|
sc->gap.bottom);
|
||||||
cc->flags |= CLIENT_VMAXIMIZED;
|
cc->flags |= CLIENT_VMAXIMIZED;
|
||||||
|
|
||||||
@ -381,43 +362,44 @@ void
|
|||||||
client_horizmaximize(struct client_ctx *cc)
|
client_horizmaximize(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc = cc->sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
int x_org = 0, xmax = sc->xmax;
|
int x_org, xmax;
|
||||||
|
XineramaScreenInfo *xine;
|
||||||
|
|
||||||
if (cc->flags & CLIENT_FREEZE)
|
if (cc->flags & CLIENT_FREEZE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cc->flags & CLIENT_HMAXIMIZED) {
|
if (cc->flags & CLIENT_HMAXIMIZED) {
|
||||||
cc->geom.x = cc->savegeom.x;
|
cc->geom.x = cc->savegeom.x;
|
||||||
cc->geom.width = cc->savegeom.width;
|
cc->geom.w = cc->savegeom.w;
|
||||||
cc->bwidth = Conf.bwidth;
|
cc->bwidth = Conf.bwidth;
|
||||||
if (cc->flags & CLIENT_VMAXIMIZED)
|
if (cc->flags & CLIENT_VMAXIMIZED)
|
||||||
cc->geom.height -= cc->bwidth * 2;
|
cc->geom.h -= cc->bwidth * 2;
|
||||||
cc->flags &= ~CLIENT_HMAXIMIZED;
|
cc->flags &= ~CLIENT_HMAXIMIZED;
|
||||||
goto resize;
|
goto resize;
|
||||||
}
|
}
|
||||||
|
|
||||||
cc->savegeom.x = cc->geom.x;
|
cc->savegeom.x = cc->geom.x;
|
||||||
cc->savegeom.width = cc->geom.width;
|
cc->savegeom.w = cc->geom.w;
|
||||||
|
|
||||||
/* if this will make us fully maximized then remove boundary */
|
/* if this will make us fully maximized then remove boundary */
|
||||||
if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_VMAXIMIZED) {
|
if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_VMAXIMIZED) {
|
||||||
cc->geom.height += cc->bwidth * 2;
|
cc->geom.h += cc->bwidth * 2;
|
||||||
cc->bwidth = 0;
|
cc->bwidth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasXinerama) {
|
|
||||||
XineramaScreenInfo *xine;
|
|
||||||
xine = screen_find_xinerama(sc,
|
xine = screen_find_xinerama(sc,
|
||||||
cc->geom.x + cc->geom.width / 2,
|
cc->geom.x + cc->geom.w / 2,
|
||||||
cc->geom.y + cc->geom.height / 2);
|
cc->geom.y + cc->geom.h / 2);
|
||||||
if (xine == NULL)
|
if (xine) {
|
||||||
goto calc;
|
|
||||||
x_org = xine->x_org;
|
x_org = xine->x_org;
|
||||||
xmax = xine->width;
|
xmax = xine->width;
|
||||||
|
} else {
|
||||||
|
x_org = 0;
|
||||||
|
xmax = sc->view.w;
|
||||||
}
|
}
|
||||||
calc:
|
|
||||||
cc->geom.x = x_org + sc->gap.left;
|
cc->geom.x = x_org + sc->gap.left;
|
||||||
cc->geom.width = xmax - (cc->bwidth * 2) - (sc->gap.left +
|
cc->geom.w = xmax - (cc->bwidth * 2) - (sc->gap.left +
|
||||||
sc->gap.right);
|
sc->gap.right);
|
||||||
cc->flags |= CLIENT_HMAXIMIZED;
|
cc->flags |= CLIENT_HMAXIMIZED;
|
||||||
|
|
||||||
@ -431,7 +413,7 @@ client_resize(struct client_ctx *cc)
|
|||||||
client_draw_border(cc);
|
client_draw_border(cc);
|
||||||
|
|
||||||
XMoveResizeWindow(X_Dpy, cc->win, cc->geom.x,
|
XMoveResizeWindow(X_Dpy, cc->win, cc->geom.x,
|
||||||
cc->geom.y, cc->geom.width, cc->geom.height);
|
cc->geom.y, cc->geom.w, cc->geom.h);
|
||||||
xu_configure(cc);
|
xu_configure(cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,8 +442,8 @@ client_ptrwarp(struct client_ctx *cc)
|
|||||||
int x = cc->ptr.x, y = cc->ptr.y;
|
int x = cc->ptr.x, y = cc->ptr.y;
|
||||||
|
|
||||||
if (x == -1 || y == -1) {
|
if (x == -1 || y == -1) {
|
||||||
x = cc->geom.width / 2;
|
x = cc->geom.w / 2;
|
||||||
y = cc->geom.height / 2;
|
y = cc->geom.h / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
(cc->state == IconicState) ? client_unhide(cc) : client_raise(cc);
|
(cc->state == IconicState) ? client_unhide(cc) : client_raise(cc);
|
||||||
@ -540,14 +522,14 @@ client_update(struct client_ctx *cc)
|
|||||||
int i;
|
int i;
|
||||||
long n;
|
long n;
|
||||||
|
|
||||||
if ((n = xu_getprop(cc->win, WM_PROTOCOLS,
|
if ((n = xu_getprop(cc->win, cwmh[WM_PROTOCOLS].atom,
|
||||||
XA_ATOM, 20L, (u_char **)&p)) <= 0)
|
XA_ATOM, 20L, (u_char **)&p)) <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
if (p[i] == WM_DELETE_WINDOW)
|
if (p[i] == cwmh[WM_DELETE_WINDOW].atom)
|
||||||
cc->xproto |= CLIENT_PROTO_DELETE;
|
cc->xproto |= CLIENT_PROTO_DELETE;
|
||||||
else if (p[i] == WM_TAKE_FOCUS)
|
else if (p[i] == cwmh[WM_TAKE_FOCUS].atom)
|
||||||
cc->xproto |= CLIENT_PROTO_TAKEFOCUS;
|
cc->xproto |= CLIENT_PROTO_TAKEFOCUS;
|
||||||
|
|
||||||
XFree(p);
|
XFree(p);
|
||||||
@ -557,7 +539,8 @@ void
|
|||||||
client_send_delete(struct client_ctx *cc)
|
client_send_delete(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
if (cc->xproto & CLIENT_PROTO_DELETE)
|
if (cc->xproto & CLIENT_PROTO_DELETE)
|
||||||
xu_sendmsg(cc->win, WM_PROTOCOLS, WM_DELETE_WINDOW);
|
xu_sendmsg(cc->win,
|
||||||
|
cwmh[WM_PROTOCOLS].atom, cwmh[WM_DELETE_WINDOW].atom);
|
||||||
else
|
else
|
||||||
XKillClient(X_Dpy, cc->win);
|
XKillClient(X_Dpy, cc->win);
|
||||||
}
|
}
|
||||||
@ -568,7 +551,7 @@ client_setname(struct client_ctx *cc)
|
|||||||
struct winname *wn;
|
struct winname *wn;
|
||||||
char *newname;
|
char *newname;
|
||||||
|
|
||||||
if (!xu_getstrprop(cc->win, _NET_WM_NAME, &newname))
|
if (!xu_getstrprop(cc->win, ewmh[_NET_WM_NAME].atom, &newname))
|
||||||
if (!xu_getstrprop(cc->win, XA_WM_NAME, &newname))
|
if (!xu_getstrprop(cc->win, XA_WM_NAME, &newname))
|
||||||
newname = emptystring;
|
newname = emptystring;
|
||||||
|
|
||||||
@ -613,7 +596,8 @@ client_cycle(struct screen_ctx *sc, int flags)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (oldcc == NULL)
|
if (oldcc == NULL)
|
||||||
oldcc = (flags & CWM_RCYCLE ? TAILQ_LAST(&sc->mruq, cycle_entry_q) :
|
oldcc = (flags & CWM_RCYCLE ?
|
||||||
|
TAILQ_LAST(&sc->mruq, cycle_entry_q) :
|
||||||
TAILQ_FIRST(&sc->mruq));
|
TAILQ_FIRST(&sc->mruq));
|
||||||
|
|
||||||
newcc = oldcc;
|
newcc = oldcc;
|
||||||
@ -637,12 +621,24 @@ client_cycle(struct screen_ctx *sc, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset when alt is released. XXX I hate this hack */
|
/* reset when cycling mod is released. XXX I hate this hack */
|
||||||
sc->altpersist = 1;
|
sc->cycling = 1;
|
||||||
client_ptrsave(oldcc);
|
client_ptrsave(oldcc);
|
||||||
client_ptrwarp(newcc);
|
client_ptrwarp(newcc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
client_cycle_leave(struct screen_ctx *sc, struct client_ctx *cc)
|
||||||
|
{
|
||||||
|
sc->cycling = 0;
|
||||||
|
|
||||||
|
client_mtf(NULL);
|
||||||
|
if (cc) {
|
||||||
|
group_sticky_toggle_exit(cc);
|
||||||
|
XUngrabKeyboard(X_Dpy, CurrentTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct client_ctx *
|
static struct client_ctx *
|
||||||
client_mrunext(struct client_ctx *cc)
|
client_mrunext(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
@ -677,8 +673,8 @@ client_placecalc(struct client_ctx *cc)
|
|||||||
* XRandR bits mean that {x,y}max shouldn't be outside what's
|
* XRandR bits mean that {x,y}max shouldn't be outside what's
|
||||||
* currently there.
|
* currently there.
|
||||||
*/
|
*/
|
||||||
xslack = sc->xmax - cc->geom.width - cc->bwidth * 2;
|
xslack = sc->view.w - cc->geom.w - cc->bwidth * 2;
|
||||||
yslack = sc->ymax - cc->geom.height - cc->bwidth * 2;
|
yslack = sc->view.h - cc->geom.h - cc->bwidth * 2;
|
||||||
if (cc->size->x > 0)
|
if (cc->size->x > 0)
|
||||||
cc->geom.x = MIN(cc->size->x, xslack);
|
cc->geom.x = MIN(cc->size->x, xslack);
|
||||||
if (cc->size->y > 0)
|
if (cc->size->y > 0)
|
||||||
@ -689,28 +685,25 @@ client_placecalc(struct client_ctx *cc)
|
|||||||
int xmax, ymax;
|
int xmax, ymax;
|
||||||
|
|
||||||
xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse);
|
xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse);
|
||||||
if (HasXinerama) {
|
|
||||||
info = screen_find_xinerama(sc, xmouse, ymouse);
|
info = screen_find_xinerama(sc, xmouse, ymouse);
|
||||||
if (info == NULL)
|
if (info) {
|
||||||
goto noxine;
|
|
||||||
xorig = info->x_org;
|
xorig = info->x_org;
|
||||||
yorig = info->y_org;
|
yorig = info->y_org;
|
||||||
xmax = xorig + info->width;
|
xmax = xorig + info->width;
|
||||||
ymax = yorig + info->height;
|
ymax = yorig + info->height;
|
||||||
} else {
|
} else {
|
||||||
noxine:
|
|
||||||
xorig = yorig = 0;
|
xorig = yorig = 0;
|
||||||
xmax = sc->xmax;
|
xmax = sc->view.w;
|
||||||
ymax = sc->ymax;
|
ymax = sc->view.h;
|
||||||
}
|
}
|
||||||
xmouse = MAX(xmouse, xorig) - cc->geom.width / 2;
|
xmouse = MAX(xmouse, xorig) - cc->geom.w / 2;
|
||||||
ymouse = MAX(ymouse, yorig) - cc->geom.height / 2;
|
ymouse = MAX(ymouse, yorig) - cc->geom.h / 2;
|
||||||
|
|
||||||
xmouse = MAX(xmouse, xorig);
|
xmouse = MAX(xmouse, xorig);
|
||||||
ymouse = MAX(ymouse, yorig);
|
ymouse = MAX(ymouse, yorig);
|
||||||
|
|
||||||
xslack = xmax - cc->geom.width - cc->bwidth * 2;
|
xslack = xmax - cc->geom.w - cc->bwidth * 2;
|
||||||
yslack = ymax - cc->geom.height - cc->bwidth * 2;
|
yslack = ymax - cc->geom.h - cc->bwidth * 2;
|
||||||
|
|
||||||
if (xslack >= xorig) {
|
if (xslack >= xorig) {
|
||||||
cc->geom.x = MAX(MIN(xmouse, xslack),
|
cc->geom.x = MAX(MIN(xmouse, xslack),
|
||||||
@ -719,7 +712,7 @@ noxine:
|
|||||||
cc->geom.x -= sc->gap.right;
|
cc->geom.x -= sc->gap.right;
|
||||||
} else {
|
} else {
|
||||||
cc->geom.x = xorig + sc->gap.left;
|
cc->geom.x = xorig + sc->gap.left;
|
||||||
cc->geom.width = xmax - sc->gap.left;
|
cc->geom.w = xmax - sc->gap.left;
|
||||||
}
|
}
|
||||||
if (yslack >= yorig) {
|
if (yslack >= yorig) {
|
||||||
cc->geom.y = MAX(MIN(ymouse, yslack),
|
cc->geom.y = MAX(MIN(ymouse, yslack),
|
||||||
@ -728,7 +721,7 @@ noxine:
|
|||||||
cc->geom.y -= sc->gap.bottom;
|
cc->geom.y -= sc->gap.bottom;
|
||||||
} else {
|
} else {
|
||||||
cc->geom.y = yorig + sc->gap.top;
|
cc->geom.y = yorig + sc->gap.top;
|
||||||
cc->geom.height = ymax - sc->gap.top;
|
cc->geom.h = ymax - sc->gap.top;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -792,6 +785,7 @@ client_getsizehints(struct client_ctx *cc)
|
|||||||
cc->size->max_aspect.y;
|
cc->size->max_aspect.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
client_applysizehints(struct client_ctx *cc)
|
client_applysizehints(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
@ -802,43 +796,43 @@ client_applysizehints(struct client_ctx *cc)
|
|||||||
|
|
||||||
/* temporarily remove base dimensions, ICCCM 4.1.2.3 */
|
/* temporarily remove base dimensions, ICCCM 4.1.2.3 */
|
||||||
if (!baseismin) {
|
if (!baseismin) {
|
||||||
cc->geom.width -= cc->hint.basew;
|
cc->geom.w -= cc->hint.basew;
|
||||||
cc->geom.height -= cc->hint.baseh;
|
cc->geom.h -= cc->hint.baseh;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adjust for aspect limits */
|
/* adjust for aspect limits */
|
||||||
if (cc->hint.mina > 0 && cc->hint.maxa > 0) {
|
if (cc->hint.mina > 0 && cc->hint.maxa > 0) {
|
||||||
if (cc->hint.maxa <
|
if (cc->hint.maxa <
|
||||||
(float)cc->geom.width / cc->geom.height)
|
(float)cc->geom.w / cc->geom.h)
|
||||||
cc->geom.width = cc->geom.height * cc->hint.maxa;
|
cc->geom.w = cc->geom.h * cc->hint.maxa;
|
||||||
else if (cc->hint.mina <
|
else if (cc->hint.mina <
|
||||||
(float)cc->geom.height / cc->geom.width)
|
(float)cc->geom.h / cc->geom.w)
|
||||||
cc->geom.height = cc->geom.width * cc->hint.mina;
|
cc->geom.h = cc->geom.w * cc->hint.mina;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove base dimensions for increment */
|
/* remove base dimensions for increment */
|
||||||
if (baseismin) {
|
if (baseismin) {
|
||||||
cc->geom.width -= cc->hint.basew;
|
cc->geom.w -= cc->hint.basew;
|
||||||
cc->geom.height -= cc->hint.baseh;
|
cc->geom.h -= cc->hint.baseh;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adjust for increment value */
|
/* adjust for increment value */
|
||||||
cc->geom.width -= cc->geom.width % cc->hint.incw;
|
cc->geom.w -= cc->geom.w % cc->hint.incw;
|
||||||
cc->geom.height -= cc->geom.height % cc->hint.inch;
|
cc->geom.h -= cc->geom.h % cc->hint.inch;
|
||||||
|
|
||||||
/* restore base dimensions */
|
/* restore base dimensions */
|
||||||
cc->geom.width += cc->hint.basew;
|
cc->geom.w += cc->hint.basew;
|
||||||
cc->geom.height += cc->hint.baseh;
|
cc->geom.h += cc->hint.baseh;
|
||||||
|
|
||||||
/* adjust for min width/height */
|
/* adjust for min width/height */
|
||||||
cc->geom.width = MAX(cc->geom.width, cc->hint.minw);
|
cc->geom.w = MAX(cc->geom.w, cc->hint.minw);
|
||||||
cc->geom.height = MAX(cc->geom.height, cc->hint.minh);
|
cc->geom.h = MAX(cc->geom.h, cc->hint.minh);
|
||||||
|
|
||||||
/* adjust for max width/height */
|
/* adjust for max width/height */
|
||||||
if (cc->hint.maxw)
|
if (cc->hint.maxw)
|
||||||
cc->geom.width = MIN(cc->geom.width, cc->hint.maxw);
|
cc->geom.w = MIN(cc->geom.w, cc->hint.maxw);
|
||||||
if (cc->hint.maxh)
|
if (cc->hint.maxh)
|
||||||
cc->geom.height = MIN(cc->geom.height, cc->hint.maxh);
|
cc->geom.h = MIN(cc->geom.h, cc->hint.maxh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -854,7 +848,7 @@ client_gethints(struct client_ctx *cc)
|
|||||||
cc->app_class = xch.res_class;
|
cc->app_class = xch.res_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xu_getprop(cc->win, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS,
|
if (xu_getprop(cc->win, cwmh[_MOTIF_WM_HINTS].atom, _MOTIF_WM_HINTS,
|
||||||
PROP_MWM_HINTS_ELEMENTS, (u_char **)&mwmh) == MWM_NUMHINTS)
|
PROP_MWM_HINTS_ELEMENTS, (u_char **)&mwmh) == MWM_NUMHINTS)
|
||||||
if (mwmh->flags & MWM_HINTS_DECORATIONS &&
|
if (mwmh->flags & MWM_HINTS_DECORATIONS &&
|
||||||
!(mwmh->decorations & MWM_DECOR_ALL) &&
|
!(mwmh->decorations & MWM_DECOR_ALL) &&
|
||||||
@ -889,8 +883,8 @@ client_transient(struct client_ctx *cc)
|
|||||||
static int
|
static int
|
||||||
client_inbound(struct client_ctx *cc, int x, int y)
|
client_inbound(struct client_ctx *cc, int x, int y)
|
||||||
{
|
{
|
||||||
return (x < cc->geom.width && x >= 0 &&
|
return (x < cc->geom.w && x >= 0 &&
|
||||||
y < cc->geom.height && y >= 0);
|
y < cc->geom.h && y >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -911,13 +905,13 @@ client_snapcalc(int n, int dn, int nmax, int bwidth, int snapdist)
|
|||||||
/* possible to snap in both directions */
|
/* possible to snap in both directions */
|
||||||
if (s0 != 0 && s1 != 0)
|
if (s0 != 0 && s1 != 0)
|
||||||
if (abs(s0) < abs(s1))
|
if (abs(s0) < abs(s1))
|
||||||
return s0;
|
return (s0);
|
||||||
else
|
else
|
||||||
return s1;
|
return (s1);
|
||||||
else if (s0 != 0)
|
else if (s0 != 0)
|
||||||
return s0;
|
return (s0);
|
||||||
else if (s1 != 0)
|
else if (s1 != 0)
|
||||||
return s1;
|
return (s1);
|
||||||
else
|
else
|
||||||
return 0;
|
return (0);
|
||||||
}
|
}
|
||||||
|
6
conf.c
6
conf.c
@ -361,8 +361,10 @@ static struct {
|
|||||||
{ "nogroup", kbfunc_client_nogroup, 0, {0} },
|
{ "nogroup", kbfunc_client_nogroup, 0, {0} },
|
||||||
{ "cyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_CYCLE} },
|
{ "cyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_CYCLE} },
|
||||||
{ "rcyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_RCYCLE} },
|
{ "rcyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_RCYCLE} },
|
||||||
{ "cycleingroup", kbfunc_client_cycle, KBFLAG_NEEDCLIENT, {.i = CWM_CYCLE|CWM_INGROUP} },
|
{ "cycleingroup", kbfunc_client_cycle, KBFLAG_NEEDCLIENT,
|
||||||
{ "rcycleingroup", kbfunc_client_cycle, KBFLAG_NEEDCLIENT, {.i = CWM_RCYCLE|CWM_INGROUP} },
|
{.i = CWM_CYCLE|CWM_INGROUP} },
|
||||||
|
{ "rcycleingroup", kbfunc_client_cycle, KBFLAG_NEEDCLIENT,
|
||||||
|
{.i = CWM_RCYCLE|CWM_INGROUP} },
|
||||||
{ "grouptoggle", kbfunc_client_grouptoggle, KBFLAG_NEEDCLIENT, {0}},
|
{ "grouptoggle", kbfunc_client_grouptoggle, KBFLAG_NEEDCLIENT, {0}},
|
||||||
{ "maximize", kbfunc_client_maximize, KBFLAG_NEEDCLIENT, {0} },
|
{ "maximize", kbfunc_client_maximize, KBFLAG_NEEDCLIENT, {0} },
|
||||||
{ "vmaximize", kbfunc_client_vmaximize, KBFLAG_NEEDCLIENT, {0} },
|
{ "vmaximize", kbfunc_client_vmaximize, KBFLAG_NEEDCLIENT, {0} },
|
||||||
|
25
cwm.1
25
cwm.1
@ -14,7 +14,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.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: September 25 2010 $
|
.Dd $Mdocdate: May 7 2012 $
|
||||||
.Dt CWM 1
|
.Dt CWM 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -258,18 +258,6 @@ option is given.
|
|||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr cwmrc 5
|
.Xr cwmrc 5
|
||||||
.Sh AUTHORS
|
|
||||||
.An -nosplit
|
|
||||||
.Pp
|
|
||||||
.Nm
|
|
||||||
was developed by
|
|
||||||
.An Marius Aamodt Eriksen Aq marius@monkey.org
|
|
||||||
with contributions from
|
|
||||||
.An Andy Adamson Aq dros@monkey.org ,
|
|
||||||
.An Niels Provos Aq provos@monkey.org ,
|
|
||||||
and
|
|
||||||
.An Antti Nyk\(:anen Aq aon@iki.fi .
|
|
||||||
Ideas, discussion with many others.
|
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
.Nm
|
.Nm
|
||||||
was originally inspired by evilwm, but was rewritten from scratch
|
was originally inspired by evilwm, but was rewritten from scratch
|
||||||
@ -280,3 +268,14 @@ has since been removed or rewritten.
|
|||||||
.Nm
|
.Nm
|
||||||
first appeared in
|
first appeared in
|
||||||
.Ox 4.2 .
|
.Ox 4.2 .
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An -nosplit
|
||||||
|
.Nm
|
||||||
|
was developed by
|
||||||
|
.An Marius Aamodt Eriksen Aq marius@monkey.org
|
||||||
|
with contributions from
|
||||||
|
.An Andy Adamson Aq dros@monkey.org ,
|
||||||
|
.An Niels Provos Aq provos@monkey.org ,
|
||||||
|
and
|
||||||
|
.An Antti Nyk\(:anen Aq aon@iki.fi .
|
||||||
|
Ideas, discussion with many others.
|
||||||
|
6
cwmrc.5
6
cwmrc.5
@ -14,7 +14,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.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: September 8 2011 $
|
.Dd $Mdocdate: November 6 2011 $
|
||||||
.Dt CWMRC 5
|
.Dt CWMRC 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -244,6 +244,10 @@ ignore xclock
|
|||||||
bind CM-r label
|
bind CM-r label
|
||||||
bind CS-Return "xterm -e top"
|
bind CS-Return "xterm -e top"
|
||||||
bind 4-o unmap
|
bind 4-o unmap
|
||||||
|
bind CM-equal unmap
|
||||||
|
bind CMS-equal unmap
|
||||||
|
bind C4-equal vmaximize
|
||||||
|
bind C4S-equal hmaximize
|
||||||
bind M-1 grouponly1
|
bind M-1 grouponly1
|
||||||
bind M-2 grouponly2
|
bind M-2 grouponly2
|
||||||
bind M-3 grouponly3
|
bind M-3 grouponly3
|
||||||
|
106
fgetln.c
106
fgetln.c
@ -1,106 +0,0 @@
|
|||||||
/* $NetBSD: fgetln.c,v 1.9 2008/04/29 06:53:03 martin Exp $ */
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to The NetBSD Foundation
|
|
||||||
* by Christos Zoulas.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
||||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
||||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_NBTOOL_CONFIG_H
|
|
||||||
#include "nbtool_config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !HAVE_FGETLN
|
|
||||||
#include <stdlib.h>
|
|
||||||
#ifndef HAVE_NBTOOL_CONFIG_H
|
|
||||||
/* These headers are required, but included from nbtool_config.h */
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *
|
|
||||||
fgetln(FILE *fp, size_t *len)
|
|
||||||
{
|
|
||||||
static char *buf = NULL;
|
|
||||||
static size_t bufsiz = 0;
|
|
||||||
char *ptr;
|
|
||||||
|
|
||||||
|
|
||||||
if (buf == NULL) {
|
|
||||||
bufsiz = BUFSIZ;
|
|
||||||
if ((buf = malloc(bufsiz)) == NULL)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fgets(buf, bufsiz, fp) == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
*len = 0;
|
|
||||||
while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
|
|
||||||
size_t nbufsiz = bufsiz + BUFSIZ;
|
|
||||||
char *nbuf = realloc(buf, nbufsiz);
|
|
||||||
|
|
||||||
if (nbuf == NULL) {
|
|
||||||
int oerrno = errno;
|
|
||||||
free(buf);
|
|
||||||
errno = oerrno;
|
|
||||||
buf = NULL;
|
|
||||||
return NULL;
|
|
||||||
} else
|
|
||||||
buf = nbuf;
|
|
||||||
|
|
||||||
if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) {
|
|
||||||
buf[bufsiz] = '\0';
|
|
||||||
*len = strlen(buf);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
*len = bufsiz;
|
|
||||||
bufsiz = nbufsiz;
|
|
||||||
}
|
|
||||||
|
|
||||||
*len = (ptr - buf) + 1;
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef TEST
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
while ((p = fgetln(stdin, &len)) != NULL) {
|
|
||||||
(void)printf("%zu %s", len, p);
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
63
group.c
63
group.c
@ -48,38 +48,31 @@ const char *shortcut_to_name[] = {
|
|||||||
static void
|
static void
|
||||||
group_add(struct group_ctx *gc, struct client_ctx *cc)
|
group_add(struct group_ctx *gc, struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
long no;
|
|
||||||
if (cc == NULL || gc == NULL)
|
if (cc == NULL || gc == NULL)
|
||||||
errx(1, "group_add: a ctx is NULL");
|
errx(1, "group_add: a ctx is NULL");
|
||||||
|
|
||||||
no = gc->shortcut - 1;
|
|
||||||
|
|
||||||
if (cc->group == gc)
|
if (cc->group == gc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cc->group != NULL)
|
if (cc->group != NULL)
|
||||||
TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
|
TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
|
||||||
|
|
||||||
XChangeProperty(X_Dpy, cc->win, _NET_WM_DESKTOP, XA_CARDINAL,
|
|
||||||
32, PropModeReplace, (unsigned char *)&no, 1);
|
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&gc->clients, cc, group_entry);
|
TAILQ_INSERT_TAIL(&gc->clients, cc, group_entry);
|
||||||
cc->group = gc;
|
cc->group = gc;
|
||||||
|
|
||||||
|
xu_ewmh_net_wm_desktop(cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
group_remove(struct client_ctx *cc)
|
group_remove(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
long no = 0xffffffff;
|
|
||||||
|
|
||||||
if (cc == NULL || cc->group == NULL)
|
if (cc == NULL || cc->group == NULL)
|
||||||
errx(1, "group_remove: a ctx is NULL");
|
errx(1, "group_remove: a ctx is NULL");
|
||||||
|
|
||||||
XChangeProperty(X_Dpy, cc->win, _NET_WM_DESKTOP, XA_CARDINAL,
|
|
||||||
32, PropModeReplace, (unsigned char *)&no, 1);
|
|
||||||
|
|
||||||
TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
|
TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
|
||||||
cc->group = NULL;
|
cc->group = NULL;
|
||||||
|
|
||||||
|
xu_ewmh_net_wm_desktop(cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -146,13 +139,12 @@ void
|
|||||||
group_init(struct screen_ctx *sc)
|
group_init(struct screen_ctx *sc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
long viewports[2] = {0, 0};
|
|
||||||
long ndesks = CALMWM_NGROUPS, zero = 0;
|
|
||||||
|
|
||||||
TAILQ_INIT(&sc->groupq);
|
TAILQ_INIT(&sc->groupq);
|
||||||
sc->group_hideall = 0;
|
sc->group_hideall = 0;
|
||||||
/* see if any group names have already been set and update the property
|
/*
|
||||||
* with ours if they'll have changed.
|
* See if any group names have already been set and update the
|
||||||
|
* property with ours if they'll have changed.
|
||||||
*/
|
*/
|
||||||
group_update_names(sc);
|
group_update_names(sc);
|
||||||
|
|
||||||
@ -163,23 +155,11 @@ group_init(struct screen_ctx *sc)
|
|||||||
TAILQ_INSERT_TAIL(&sc->groupq, &sc->groups[i], entry);
|
TAILQ_INSERT_TAIL(&sc->groupq, &sc->groups[i], entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we don't support large desktops, so this is always (0, 0) */
|
xu_ewmh_net_wm_desktop_viewport(sc);
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_VIEWPORT,
|
xu_ewmh_net_wm_number_of_desktops(sc);
|
||||||
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2);
|
xu_ewmh_net_showing_desktop(sc);
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, _NET_NUMBER_OF_DESKTOPS,
|
xu_ewmh_net_virtual_roots(sc);
|
||||||
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&ndesks, 1);
|
|
||||||
/*
|
|
||||||
* we don't use virtual roots, so make sure it's not there from a
|
|
||||||
* previous wm.
|
|
||||||
*/
|
|
||||||
XDeleteProperty(X_Dpy, sc->rootwin, _NET_VIRTUAL_ROOTS);
|
|
||||||
/*
|
|
||||||
* We don't really have a ``showing desktop'' mode, so this is zero
|
|
||||||
* always. XXX Note that when we hide all groups, or when all groups
|
|
||||||
* are hidden we could technically set this later on.
|
|
||||||
*/
|
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, _NET_SHOWING_DESKTOP,
|
|
||||||
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&zero, 1);
|
|
||||||
group_setactive(sc, 0);
|
group_setactive(sc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,8 +188,8 @@ static void
|
|||||||
group_setactive(struct screen_ctx *sc, long idx)
|
group_setactive(struct screen_ctx *sc, long idx)
|
||||||
{
|
{
|
||||||
sc->group_active = &sc->groups[idx];
|
sc->group_active = &sc->groups[idx];
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, _NET_CURRENT_DESKTOP,
|
|
||||||
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&idx, 1);
|
xu_ewmh_net_current_desktop(sc, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -438,8 +418,8 @@ group_autogroup(struct client_ctx *cc)
|
|||||||
if (cc->app_class == NULL || cc->app_name == NULL)
|
if (cc->app_class == NULL || cc->app_name == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (xu_getprop(cc->win, _NET_WM_DESKTOP, XA_CARDINAL,
|
if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP].atom,
|
||||||
1, (unsigned char **)&grpno) > 0) {
|
XA_CARDINAL, 1, (unsigned char **)&grpno) > 0) {
|
||||||
if (*grpno == 0xffffffff)
|
if (*grpno == 0xffffffff)
|
||||||
no = 0;
|
no = 0;
|
||||||
else if (*grpno > CALMWM_NGROUPS || *grpno < 0)
|
else if (*grpno > CALMWM_NGROUPS || *grpno < 0)
|
||||||
@ -479,11 +459,12 @@ group_update_names(struct screen_ctx *sc)
|
|||||||
char **strings, *p;
|
char **strings, *p;
|
||||||
unsigned char *prop_ret;
|
unsigned char *prop_ret;
|
||||||
Atom type_ret;
|
Atom type_ret;
|
||||||
int format_ret, i = 0, nstrings = 0, n, setnames = 0;
|
int format_ret, i = 0, nstrings = 0, n = 0, setnames = 0;
|
||||||
unsigned long bytes_after, num_ret;
|
unsigned long bytes_after, num_ret;
|
||||||
|
|
||||||
if (XGetWindowProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_NAMES, 0,
|
if (XGetWindowProperty(X_Dpy, sc->rootwin,
|
||||||
0xffffff, False, UTF8_STRING, &type_ret, &format_ret,
|
ewmh[_NET_DESKTOP_NAMES].atom, 0, 0xffffff, False,
|
||||||
|
cwmh[UTF8_STRING].atom, &type_ret, &format_ret,
|
||||||
&num_ret, &bytes_after, &prop_ret) == Success &&
|
&num_ret, &bytes_after, &prop_ret) == Success &&
|
||||||
prop_ret != NULL && format_ret == 8) {
|
prop_ret != NULL && format_ret == 8) {
|
||||||
/* failure, just set defaults */
|
/* failure, just set defaults */
|
||||||
@ -497,7 +478,6 @@ group_update_names(struct screen_ctx *sc)
|
|||||||
strings = xmalloc((nstrings < CALMWM_NGROUPS ? CALMWM_NGROUPS :
|
strings = xmalloc((nstrings < CALMWM_NGROUPS ? CALMWM_NGROUPS :
|
||||||
nstrings) * sizeof(*strings));
|
nstrings) * sizeof(*strings));
|
||||||
|
|
||||||
i = n = 0;
|
|
||||||
p = prop_ret;
|
p = prop_ret;
|
||||||
while (n < nstrings) {
|
while (n < nstrings) {
|
||||||
strings[n++] = xstrdup(p);
|
strings[n++] = xstrdup(p);
|
||||||
@ -544,6 +524,5 @@ group_set_names(struct screen_ctx *sc)
|
|||||||
q += slen;
|
q += slen;
|
||||||
}
|
}
|
||||||
|
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_NAMES,
|
xu_ewmh_net_desktop_names(sc, p, len);
|
||||||
UTF8_STRING, 8, PropModeReplace, p, len);
|
|
||||||
}
|
}
|
||||||
|
57
kbfunc.c
57
kbfunc.c
@ -25,7 +25,6 @@
|
|||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -55,14 +54,13 @@ kbfunc_client_raise(struct client_ctx *cc, union arg *arg)
|
|||||||
void
|
void
|
||||||
kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
|
kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
int x, y, flags, amt;
|
int x, y, flags, amt;
|
||||||
u_int mx, my;
|
u_int mx, my;
|
||||||
|
|
||||||
if (cc->flags & CLIENT_FREEZE)
|
if (cc->flags & CLIENT_FREEZE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sc = cc->sc;
|
|
||||||
mx = my = 0;
|
mx = my = 0;
|
||||||
|
|
||||||
flags = arg->i;
|
flags = arg->i;
|
||||||
@ -90,22 +88,22 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
|
|||||||
switch (flags & TYPEMASK) {
|
switch (flags & TYPEMASK) {
|
||||||
case CWM_MOVE:
|
case CWM_MOVE:
|
||||||
cc->geom.y += my;
|
cc->geom.y += my;
|
||||||
if (cc->geom.y + cc->geom.height < 0)
|
if (cc->geom.y + cc->geom.h < 0)
|
||||||
cc->geom.y = -cc->geom.height;
|
cc->geom.y = -cc->geom.h;
|
||||||
if (cc->geom.y > cc->sc->ymax - 1)
|
if (cc->geom.y > sc->view.h - 1)
|
||||||
cc->geom.y = cc->sc->ymax - 1;
|
cc->geom.y = sc->view.h - 1;
|
||||||
|
|
||||||
cc->geom.x += mx;
|
cc->geom.x += mx;
|
||||||
if (cc->geom.x + cc->geom.width < 0)
|
if (cc->geom.x + cc->geom.w < 0)
|
||||||
cc->geom.x = -cc->geom.width;
|
cc->geom.x = -cc->geom.w;
|
||||||
if (cc->geom.x > cc->sc->xmax - 1)
|
if (cc->geom.x > sc->view.w - 1)
|
||||||
cc->geom.x = cc->sc->xmax - 1;
|
cc->geom.x = sc->view.w - 1;
|
||||||
|
|
||||||
cc->geom.x += client_snapcalc(cc->geom.x,
|
cc->geom.x += client_snapcalc(cc->geom.x,
|
||||||
cc->geom.width, cc->sc->xmax,
|
cc->geom.w, sc->view.w,
|
||||||
cc->bwidth, Conf.snapdist);
|
cc->bwidth, Conf.snapdist);
|
||||||
cc->geom.y += client_snapcalc(cc->geom.y,
|
cc->geom.y += client_snapcalc(cc->geom.y,
|
||||||
cc->geom.height, cc->sc->ymax,
|
cc->geom.h, sc->view.h,
|
||||||
cc->bwidth, Conf.snapdist);
|
cc->bwidth, Conf.snapdist);
|
||||||
|
|
||||||
client_move(cc);
|
client_move(cc);
|
||||||
@ -115,18 +113,18 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
|
|||||||
client_ptrwarp(cc);
|
client_ptrwarp(cc);
|
||||||
break;
|
break;
|
||||||
case CWM_RESIZE:
|
case CWM_RESIZE:
|
||||||
if ((cc->geom.height += my) < 1)
|
if ((cc->geom.h += my) < 1)
|
||||||
cc->geom.height = 1;
|
cc->geom.h = 1;
|
||||||
if ((cc->geom.width += mx) < 1)
|
if ((cc->geom.w += mx) < 1)
|
||||||
cc->geom.width = 1;
|
cc->geom.w = 1;
|
||||||
client_resize(cc);
|
client_resize(cc);
|
||||||
|
|
||||||
/* Make sure the pointer stays within the window. */
|
/* Make sure the pointer stays within the window. */
|
||||||
xu_ptr_getpos(cc->win, &cc->ptr.x, &cc->ptr.y);
|
xu_ptr_getpos(cc->win, &cc->ptr.x, &cc->ptr.y);
|
||||||
if (cc->ptr.x > cc->geom.width)
|
if (cc->ptr.x > cc->geom.w)
|
||||||
cc->ptr.x = cc->geom.width - cc->bwidth;
|
cc->ptr.x = cc->geom.w - cc->bwidth;
|
||||||
if (cc->ptr.y > cc->geom.height)
|
if (cc->ptr.y > cc->geom.h)
|
||||||
cc->ptr.y = cc->geom.height - cc->bwidth;
|
cc->ptr.y = cc->geom.h - cc->bwidth;
|
||||||
client_ptrwarp(cc);
|
client_ptrwarp(cc);
|
||||||
break;
|
break;
|
||||||
case CWM_PTRMOVE:
|
case CWM_PTRMOVE:
|
||||||
@ -141,12 +139,11 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
|
|||||||
void
|
void
|
||||||
kbfunc_client_search(struct client_ctx *cc, union arg *arg)
|
kbfunc_client_search(struct client_ctx *cc, union arg *arg)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
struct client_ctx *old_cc;
|
struct client_ctx *old_cc;
|
||||||
struct menu *mi;
|
struct menu *mi;
|
||||||
struct menu_q menuq;
|
struct menu_q menuq;
|
||||||
|
|
||||||
sc = cc->sc;
|
|
||||||
old_cc = client_current();
|
old_cc = client_current();
|
||||||
|
|
||||||
TAILQ_INIT(&menuq);
|
TAILQ_INIT(&menuq);
|
||||||
@ -178,12 +175,11 @@ kbfunc_client_search(struct client_ctx *cc, union arg *arg)
|
|||||||
void
|
void
|
||||||
kbfunc_menu_search(struct client_ctx *cc, union arg *arg)
|
kbfunc_menu_search(struct client_ctx *cc, union arg *arg)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
struct cmd *cmd;
|
struct cmd *cmd;
|
||||||
struct menu *mi;
|
struct menu *mi;
|
||||||
struct menu_q menuq;
|
struct menu_q menuq;
|
||||||
|
|
||||||
sc = cc->sc;
|
|
||||||
TAILQ_INIT(&menuq);
|
TAILQ_INIT(&menuq);
|
||||||
|
|
||||||
TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
|
TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
|
||||||
@ -206,9 +202,7 @@ kbfunc_menu_search(struct client_ctx *cc, union arg *arg)
|
|||||||
void
|
void
|
||||||
kbfunc_client_cycle(struct client_ctx *cc, union arg *arg)
|
kbfunc_client_cycle(struct client_ctx *cc, union arg *arg)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
|
|
||||||
sc = cc->sc;
|
|
||||||
|
|
||||||
/* XXX for X apps that ignore events */
|
/* XXX for X apps that ignore events */
|
||||||
XGrabKeyboard(X_Dpy, sc->rootwin, True,
|
XGrabKeyboard(X_Dpy, sc->rootwin, True,
|
||||||
@ -245,7 +239,7 @@ void
|
|||||||
kbfunc_exec(struct client_ctx *cc, union arg *arg)
|
kbfunc_exec(struct client_ctx *cc, union arg *arg)
|
||||||
{
|
{
|
||||||
#define NPATHS 256
|
#define NPATHS 256
|
||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
char **ap, *paths[NPATHS], *path, *pathcpy, *label;
|
char **ap, *paths[NPATHS], *path, *pathcpy, *label;
|
||||||
char tpath[MAXPATHLEN];
|
char tpath[MAXPATHLEN];
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
@ -254,7 +248,6 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg)
|
|||||||
struct menu_q menuq;
|
struct menu_q menuq;
|
||||||
int l, i, cmd = arg->i;
|
int l, i, cmd = arg->i;
|
||||||
|
|
||||||
sc = cc->sc;
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case CWM_EXEC_PROGRAM:
|
case CWM_EXEC_PROGRAM:
|
||||||
label = "exec";
|
label = "exec";
|
||||||
@ -333,7 +326,7 @@ out:
|
|||||||
void
|
void
|
||||||
kbfunc_ssh(struct client_ctx *cc, union arg *arg)
|
kbfunc_ssh(struct client_ctx *cc, union arg *arg)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
struct menu *mi;
|
struct menu *mi;
|
||||||
struct menu_q menuq;
|
struct menu_q menuq;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
@ -343,8 +336,6 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg)
|
|||||||
int l;
|
int l;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
sc = cc->sc;
|
|
||||||
|
|
||||||
if ((home = getenv("HOME")) == NULL)
|
if ((home = getenv("HOME")) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
6
menu.c
6
menu.c
@ -349,8 +349,8 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
|
|||||||
ymax = xine->y_org + xine->height;
|
ymax = xine->y_org + xine->height;
|
||||||
} else {
|
} else {
|
||||||
xmin = ymin = 0;
|
xmin = ymin = 0;
|
||||||
xmax = sc->xmax;
|
xmax = sc->view.w;
|
||||||
ymax = sc->ymax;
|
ymax = sc->view.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
xsave = mc->x;
|
xsave = mc->x;
|
||||||
@ -466,7 +466,7 @@ menu_keycode(KeyCode kc, u_int state, enum ctltype *ctl, char *chr)
|
|||||||
*ctl = CTL_NONE;
|
*ctl = CTL_NONE;
|
||||||
*chr = '\0';
|
*chr = '\0';
|
||||||
|
|
||||||
ks = XKeycodeToKeysym(X_Dpy, kc, (state & ShiftMask) ? 1 : 0);
|
ks = XkbKeycodeToKeysym(X_Dpy, kc, 0, (state & ShiftMask) ? 1 : 0);
|
||||||
|
|
||||||
/* Look for control characters. */
|
/* Look for control characters. */
|
||||||
switch (ks) {
|
switch (ks) {
|
||||||
|
38
mousefunc.c
38
mousefunc.c
@ -37,17 +37,17 @@ static void mousefunc_sweep_draw(struct client_ctx *);
|
|||||||
static int
|
static int
|
||||||
mousefunc_sweep_calc(struct client_ctx *cc, int x, int y, int mx, int my)
|
mousefunc_sweep_calc(struct client_ctx *cc, int x, int y, int mx, int my)
|
||||||
{
|
{
|
||||||
int width = cc->geom.width, height = cc->geom.height;
|
int width = cc->geom.w, height = cc->geom.h;
|
||||||
|
|
||||||
cc->geom.width = abs(x - mx) - cc->bwidth;
|
cc->geom.w = abs(x - mx) - cc->bwidth;
|
||||||
cc->geom.height = abs(y - my) - cc->bwidth;
|
cc->geom.h = abs(y - my) - cc->bwidth;
|
||||||
|
|
||||||
client_applysizehints(cc);
|
client_applysizehints(cc);
|
||||||
|
|
||||||
cc->geom.x = x <= mx ? x : x - cc->geom.width;
|
cc->geom.x = x <= mx ? x : x - cc->geom.w;
|
||||||
cc->geom.y = y <= my ? y : y - cc->geom.height;
|
cc->geom.y = y <= my ? y : y - cc->geom.h;
|
||||||
|
|
||||||
return (width != cc->geom.width || height != cc->geom.height);
|
return (width != cc->geom.w || height != cc->geom.h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -58,8 +58,8 @@ mousefunc_sweep_draw(struct client_ctx *cc)
|
|||||||
int width, width_size, width_name;
|
int width, width_size, width_name;
|
||||||
|
|
||||||
(void)snprintf(asize, sizeof(asize), "%dx%d",
|
(void)snprintf(asize, sizeof(asize), "%dx%d",
|
||||||
(cc->geom.width - cc->hint.basew) / cc->hint.incw,
|
(cc->geom.w - cc->hint.basew) / cc->hint.incw,
|
||||||
(cc->geom.height - cc->hint.baseh) / cc->hint.inch);
|
(cc->geom.h - cc->hint.baseh) / cc->hint.inch);
|
||||||
width_size = font_width(sc, asize, strlen(asize)) + 4;
|
width_size = font_width(sc, asize, strlen(asize)) + 4;
|
||||||
width_name = font_width(sc, cc->name, strlen(cc->name)) + 4;
|
width_name = font_width(sc, cc->name, strlen(cc->name)) + 4;
|
||||||
width = MAX(width_size, width_name);
|
width = MAX(width_size, width_name);
|
||||||
@ -91,7 +91,7 @@ mousefunc_window_resize(struct client_ctx *cc, void *arg)
|
|||||||
if (xu_ptr_grab(cc->win, MOUSEMASK, Cursor_resize) < 0)
|
if (xu_ptr_grab(cc->win, MOUSEMASK, Cursor_resize) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xu_ptr_setpos(cc->win, cc->geom.width, cc->geom.height);
|
xu_ptr_setpos(cc->win, cc->geom.w, cc->geom.h);
|
||||||
mousefunc_sweep_draw(cc);
|
mousefunc_sweep_draw(cc);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -121,10 +121,10 @@ mousefunc_window_resize(struct client_ctx *cc, void *arg)
|
|||||||
xu_ptr_ungrab();
|
xu_ptr_ungrab();
|
||||||
|
|
||||||
/* Make sure the pointer stays within the window. */
|
/* Make sure the pointer stays within the window. */
|
||||||
if (cc->ptr.x > cc->geom.width)
|
if (cc->ptr.x > cc->geom.w)
|
||||||
cc->ptr.x = cc->geom.width - cc->bwidth;
|
cc->ptr.x = cc->geom.w - cc->bwidth;
|
||||||
if (cc->ptr.y > cc->geom.height)
|
if (cc->ptr.y > cc->geom.h)
|
||||||
cc->ptr.y = cc->geom.height - cc->bwidth;
|
cc->ptr.y = cc->geom.h - cc->bwidth;
|
||||||
client_ptrwarp(cc);
|
client_ptrwarp(cc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -137,6 +137,7 @@ mousefunc_window_move(struct client_ctx *cc, void *arg)
|
|||||||
{
|
{
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
Time ltime = 0;
|
Time ltime = 0;
|
||||||
|
struct screen_ctx *sc = cc->sc;
|
||||||
int px, py;
|
int px, py;
|
||||||
|
|
||||||
client_raise(cc);
|
client_raise(cc);
|
||||||
@ -161,10 +162,10 @@ mousefunc_window_move(struct client_ctx *cc, void *arg)
|
|||||||
cc->geom.y = ev.xmotion.y_root - py - cc->bwidth;
|
cc->geom.y = ev.xmotion.y_root - py - cc->bwidth;
|
||||||
|
|
||||||
cc->geom.x += client_snapcalc(cc->geom.x,
|
cc->geom.x += client_snapcalc(cc->geom.x,
|
||||||
cc->geom.width, cc->sc->xmax,
|
cc->geom.w, sc->view.w,
|
||||||
cc->bwidth, Conf.snapdist);
|
cc->bwidth, Conf.snapdist);
|
||||||
cc->geom.y += client_snapcalc(cc->geom.y,
|
cc->geom.y += client_snapcalc(cc->geom.y,
|
||||||
cc->geom.height, cc->sc->ymax,
|
cc->geom.h, sc->view.h,
|
||||||
cc->bwidth, Conf.snapdist);
|
cc->bwidth, Conf.snapdist);
|
||||||
|
|
||||||
/* don't move more than 60 times / second */
|
/* don't move more than 60 times / second */
|
||||||
@ -217,13 +218,12 @@ mousefunc_menu_group(struct client_ctx *cc, void *arg)
|
|||||||
void
|
void
|
||||||
mousefunc_menu_unhide(struct client_ctx *cc, void *arg)
|
mousefunc_menu_unhide(struct client_ctx *cc, void *arg)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
struct client_ctx *old_cc;
|
struct client_ctx *old_cc;
|
||||||
struct menu *mi;
|
struct menu *mi;
|
||||||
struct menu_q menuq;
|
struct menu_q menuq;
|
||||||
char *wname;
|
char *wname;
|
||||||
|
|
||||||
sc = cc->sc;
|
|
||||||
old_cc = client_current();
|
old_cc = client_current();
|
||||||
|
|
||||||
TAILQ_INIT(&menuq);
|
TAILQ_INIT(&menuq);
|
||||||
@ -261,13 +261,11 @@ mousefunc_menu_unhide(struct client_ctx *cc, void *arg)
|
|||||||
void
|
void
|
||||||
mousefunc_menu_cmd(struct client_ctx *cc, void *arg)
|
mousefunc_menu_cmd(struct client_ctx *cc, void *arg)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
struct menu *mi;
|
struct menu *mi;
|
||||||
struct menu_q menuq;
|
struct menu_q menuq;
|
||||||
struct cmd *cmd;
|
struct cmd *cmd;
|
||||||
|
|
||||||
sc = cc->sc;
|
|
||||||
|
|
||||||
TAILQ_INIT(&menuq);
|
TAILQ_INIT(&menuq);
|
||||||
TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
|
TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
|
||||||
mi = xcalloc(1, sizeof(*mi));
|
mi = xcalloc(1, sizeof(*mi));
|
||||||
|
54
screen.c
54
screen.c
@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#include "calmwm.h"
|
#include "calmwm.h"
|
||||||
|
|
||||||
|
static void screen_init_xinerama(struct screen_ctx *);
|
||||||
|
|
||||||
struct screen_ctx *
|
struct screen_ctx *
|
||||||
screen_fromroot(Window rootwin)
|
screen_fromroot(Window rootwin)
|
||||||
{
|
{
|
||||||
@ -65,24 +67,18 @@ screen_updatestackingorder(struct screen_ctx *sc)
|
|||||||
XFree(wins);
|
XFree(wins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're using RandR then we'll redo this whenever the screen
|
||||||
|
* changes since a CTRC may have been added or removed
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
screen_init_xinerama(struct screen_ctx *sc)
|
screen_init_xinerama(struct screen_ctx *sc)
|
||||||
{
|
{
|
||||||
XineramaScreenInfo *info;
|
XineramaScreenInfo *info = NULL;
|
||||||
int no;
|
int no = 0;
|
||||||
|
|
||||||
if (HasXinerama == 0 || XineramaIsActive(X_Dpy) == 0) {
|
|
||||||
HasXinerama = 0;
|
|
||||||
sc->xinerama_no = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (XineramaIsActive(X_Dpy))
|
||||||
info = XineramaQueryScreens(X_Dpy, &no);
|
info = XineramaQueryScreens(X_Dpy, &no);
|
||||||
if (info == NULL) {
|
|
||||||
/* Is xinerama actually off, instead of a malloc failure? */
|
|
||||||
if (sc->xinerama == NULL)
|
|
||||||
HasXinerama = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sc->xinerama != NULL)
|
if (sc->xinerama != NULL)
|
||||||
XFree(sc->xinerama);
|
XFree(sc->xinerama);
|
||||||
@ -99,6 +95,9 @@ screen_find_xinerama(struct screen_ctx *sc, int x, int y)
|
|||||||
XineramaScreenInfo *info;
|
XineramaScreenInfo *info;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (sc->xinerama == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
for (i = 0; i < sc->xinerama_no; i++) {
|
for (i = 0; i < sc->xinerama_no; i++) {
|
||||||
info = &sc->xinerama[i];
|
info = &sc->xinerama[i];
|
||||||
if (x >= info->x_org && x < info->x_org + info->width &&
|
if (x >= info->x_org && x < info->x_org + info->width &&
|
||||||
@ -109,25 +108,20 @@ screen_find_xinerama(struct screen_ctx *sc, int x, int y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_update_geometry(struct screen_ctx *sc, int width, int height)
|
screen_update_geometry(struct screen_ctx *sc)
|
||||||
{
|
{
|
||||||
long geom[2], workareas[CALMWM_NGROUPS][4];
|
sc->view.x = 0;
|
||||||
int i;
|
sc->view.y = 0;
|
||||||
|
sc->view.w = DisplayWidth(X_Dpy, sc->which);
|
||||||
|
sc->view.h = DisplayHeight(X_Dpy, sc->which);
|
||||||
|
|
||||||
sc->xmax = geom[0] = width;
|
sc->work.x = sc->view.x + sc->gap.left;
|
||||||
sc->ymax = geom[1] = height;
|
sc->work.y = sc->view.y + sc->gap.top;
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_GEOMETRY,
|
sc->work.w = sc->view.w - (sc->gap.left + sc->gap.right);
|
||||||
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)geom , 2);
|
sc->work.h = sc->view.h - (sc->gap.top + sc->gap.bottom);
|
||||||
|
|
||||||
/* x, y, width, height. */
|
screen_init_xinerama(sc);
|
||||||
for (i = 0; i < CALMWM_NGROUPS; i++) {
|
|
||||||
workareas[i][0] = sc->gap.left;
|
|
||||||
workareas[i][1] = sc->gap.top;
|
|
||||||
workareas[i][2] = width - (sc->gap.left + sc->gap.right);
|
|
||||||
workareas[i][3] = height - (sc->gap.top + sc->gap.bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, _NET_WORKAREA,
|
xu_ewmh_net_desktop_geometry(sc);
|
||||||
XA_CARDINAL, 32, PropModeReplace,
|
xu_ewmh_net_workarea(sc);
|
||||||
(unsigned char *)workareas, CALMWM_NGROUPS * 4);
|
|
||||||
}
|
}
|
||||||
|
61
strlcat.c
61
strlcat.c
@ -1,61 +0,0 @@
|
|||||||
/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */
|
|
||||||
|
|
||||||
#ifndef HAVE_STRLCAT
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
|
||||||
* full size of dst, not space left). At most siz-1 characters
|
|
||||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
|
||||||
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
|
||||||
* If retval >= siz, truncation occurred.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
strlcat(char *dst, const char *src, size_t siz)
|
|
||||||
{
|
|
||||||
char *d = dst;
|
|
||||||
const char *s = src;
|
|
||||||
size_t n = siz;
|
|
||||||
size_t dlen;
|
|
||||||
|
|
||||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
|
||||||
while (n-- != 0 && *d != '\0')
|
|
||||||
d++;
|
|
||||||
dlen = d - dst;
|
|
||||||
n = siz - dlen;
|
|
||||||
|
|
||||||
if (n == 0)
|
|
||||||
return(dlen + strlen(s));
|
|
||||||
while (*s != '\0') {
|
|
||||||
if (n != 1) {
|
|
||||||
*d++ = *s;
|
|
||||||
n--;
|
|
||||||
}
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
*d = '\0';
|
|
||||||
|
|
||||||
return(dlen + (s - src)); /* count does not include NUL */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !HAVE_STRLCAT */
|
|
57
strlcpy.c
57
strlcpy.c
@ -1,57 +0,0 @@
|
|||||||
/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */
|
|
||||||
|
|
||||||
#ifndef HAVE_STRLCPY
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy src to string dst of size siz. At most siz-1 characters
|
|
||||||
* will be copied. Always NUL terminates (unless siz == 0).
|
|
||||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
strlcpy(char *dst, const char *src, size_t siz)
|
|
||||||
{
|
|
||||||
char *d = dst;
|
|
||||||
const char *s = src;
|
|
||||||
size_t n = siz;
|
|
||||||
|
|
||||||
/* Copy as many bytes as will fit */
|
|
||||||
if (n != 0 && --n != 0) {
|
|
||||||
do {
|
|
||||||
if ((*d++ = *s++) == 0)
|
|
||||||
break;
|
|
||||||
} while (--n != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
|
||||||
if (n == 0) {
|
|
||||||
if (siz != 0)
|
|
||||||
*d = '\0'; /* NUL-terminate dst */
|
|
||||||
while (*s++)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(s - src - 1); /* count does not include NUL */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !HAVE_STRLCPY */
|
|
70
strtonum.c
70
strtonum.c
@ -1,70 +0,0 @@
|
|||||||
/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2004 Ted Unangst and Todd Miller
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* OPENBSD ORIGINAL: lib/libc/stdlib/strtonum.c */
|
|
||||||
|
|
||||||
#ifndef HAVE_STRTONUM
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#define INVALID 1
|
|
||||||
#define TOOSMALL 2
|
|
||||||
#define TOOLARGE 3
|
|
||||||
|
|
||||||
long long
|
|
||||||
strtonum(const char *numstr, long long minval, long long maxval,
|
|
||||||
const char **errstrp)
|
|
||||||
{
|
|
||||||
long long ll = 0;
|
|
||||||
char *ep;
|
|
||||||
int error = 0;
|
|
||||||
struct errval {
|
|
||||||
const char *errstr;
|
|
||||||
int err;
|
|
||||||
} ev[4] = {
|
|
||||||
{ NULL, 0 },
|
|
||||||
{ "invalid", EINVAL },
|
|
||||||
{ "too small", ERANGE },
|
|
||||||
{ "too large", ERANGE },
|
|
||||||
};
|
|
||||||
|
|
||||||
ev[0].err = errno;
|
|
||||||
errno = 0;
|
|
||||||
if (minval > maxval)
|
|
||||||
error = INVALID;
|
|
||||||
else {
|
|
||||||
ll = strtoll(numstr, &ep, 10);
|
|
||||||
if (numstr == ep || *ep != '\0')
|
|
||||||
error = INVALID;
|
|
||||||
else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
|
|
||||||
error = TOOSMALL;
|
|
||||||
else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
|
|
||||||
error = TOOLARGE;
|
|
||||||
}
|
|
||||||
if (errstrp != NULL)
|
|
||||||
*errstrp = ev[error].errstr;
|
|
||||||
errno = ev[error].err;
|
|
||||||
if (error)
|
|
||||||
ll = 0;
|
|
||||||
|
|
||||||
return (ll);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_STRTONUM */
|
|
52
xevents.c
52
xevents.c
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -71,6 +70,9 @@ void (*xev_handlers[LASTEvent])(XEvent *) = {
|
|||||||
[MappingNotify] = xev_handle_mappingnotify,
|
[MappingNotify] = xev_handle_mappingnotify,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static KeySym modkeys[] = { XK_Alt_L, XK_Alt_R, XK_Super_L, XK_Super_R,
|
||||||
|
XK_Control_L, XK_Control_R };
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xev_handle_maprequest(XEvent *ee)
|
xev_handle_maprequest(XEvent *ee)
|
||||||
{
|
{
|
||||||
@ -139,9 +141,9 @@ xev_handle_configurerequest(XEvent *ee)
|
|||||||
sc = cc->sc;
|
sc = cc->sc;
|
||||||
|
|
||||||
if (e->value_mask & CWWidth)
|
if (e->value_mask & CWWidth)
|
||||||
cc->geom.width = e->width;
|
cc->geom.w = e->width;
|
||||||
if (e->value_mask & CWHeight)
|
if (e->value_mask & CWHeight)
|
||||||
cc->geom.height = e->height;
|
cc->geom.h = e->height;
|
||||||
if (e->value_mask & CWX)
|
if (e->value_mask & CWX)
|
||||||
cc->geom.x = e->x;
|
cc->geom.x = e->x;
|
||||||
if (e->value_mask & CWY)
|
if (e->value_mask & CWY)
|
||||||
@ -149,16 +151,16 @@ xev_handle_configurerequest(XEvent *ee)
|
|||||||
if (e->value_mask & CWBorderWidth)
|
if (e->value_mask & CWBorderWidth)
|
||||||
wc.border_width = e->border_width;
|
wc.border_width = e->border_width;
|
||||||
|
|
||||||
if (cc->geom.x == 0 && cc->geom.width >= sc->xmax)
|
if (cc->geom.x == 0 && cc->geom.w >= sc->view.w)
|
||||||
cc->geom.x -= cc->bwidth;
|
cc->geom.x -= cc->bwidth;
|
||||||
|
|
||||||
if (cc->geom.y == 0 && cc->geom.height >= sc->ymax)
|
if (cc->geom.y == 0 && cc->geom.h >= sc->view.h)
|
||||||
cc->geom.y -= cc->bwidth;
|
cc->geom.y -= cc->bwidth;
|
||||||
|
|
||||||
wc.x = cc->geom.x;
|
wc.x = cc->geom.x;
|
||||||
wc.y = cc->geom.y;
|
wc.y = cc->geom.y;
|
||||||
wc.width = cc->geom.width;
|
wc.width = cc->geom.w;
|
||||||
wc.height = cc->geom.height;
|
wc.height = cc->geom.h;
|
||||||
wc.border_width = cc->bwidth;
|
wc.border_width = cc->bwidth;
|
||||||
|
|
||||||
XConfigureWindow(X_Dpy, cc->win, e->value_mask, &wc);
|
XConfigureWindow(X_Dpy, cc->win, e->value_mask, &wc);
|
||||||
@ -204,12 +206,10 @@ xev_handle_propertynotify(XEvent *ee)
|
|||||||
if (sc->rootwin == e->window)
|
if (sc->rootwin == e->window)
|
||||||
goto test;
|
goto test;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
test:
|
test:
|
||||||
if (e->atom == _NET_DESKTOP_NAMES)
|
if (e->atom == ewmh[_NET_DESKTOP_NAMES].atom)
|
||||||
group_update_names(sc);
|
group_update_names(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -279,8 +279,8 @@ xev_handle_keypress(XEvent *ee)
|
|||||||
KeySym keysym, skeysym;
|
KeySym keysym, skeysym;
|
||||||
int modshift;
|
int modshift;
|
||||||
|
|
||||||
keysym = XKeycodeToKeysym(X_Dpy, e->keycode, 0);
|
keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0);
|
||||||
skeysym = XKeycodeToKeysym(X_Dpy, e->keycode, 1);
|
skeysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 1);
|
||||||
|
|
||||||
/* we don't care about caps lock and numlock here */
|
/* we don't care about caps lock and numlock here */
|
||||||
e->state &= ~(LockMask | Mod2Mask);
|
e->state &= ~(LockMask | Mod2Mask);
|
||||||
@ -315,7 +315,7 @@ xev_handle_keypress(XEvent *ee)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is only used for the alt suppression detection.
|
* This is only used for the modifier suppression detection.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
xev_handle_keyrelease(XEvent *ee)
|
xev_handle_keyrelease(XEvent *ee)
|
||||||
@ -323,26 +323,17 @@ xev_handle_keyrelease(XEvent *ee)
|
|||||||
XKeyEvent *e = &ee->xkey;
|
XKeyEvent *e = &ee->xkey;
|
||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc;
|
||||||
struct client_ctx *cc;
|
struct client_ctx *cc;
|
||||||
int keysym;
|
int i, keysym;
|
||||||
|
|
||||||
sc = screen_fromroot(e->root);
|
sc = screen_fromroot(e->root);
|
||||||
cc = client_current();
|
cc = client_current();
|
||||||
|
|
||||||
keysym = XKeycodeToKeysym(X_Dpy, e->keycode, 0);
|
keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0);
|
||||||
if (keysym != XK_Alt_L && keysym != XK_Alt_R)
|
for (i = 0; i < nitems(modkeys); i++) {
|
||||||
return;
|
if (keysym == modkeys[i]) {
|
||||||
|
client_cycle_leave(sc, cc);
|
||||||
sc->altpersist = 0;
|
break;
|
||||||
|
}
|
||||||
/*
|
|
||||||
* XXX - better interface... xevents should not know about
|
|
||||||
* how/when to mtf.
|
|
||||||
*/
|
|
||||||
client_mtf(NULL);
|
|
||||||
|
|
||||||
if (cc != NULL) {
|
|
||||||
group_sticky_toggle_exit(cc);
|
|
||||||
XUngrabKeyboard(X_Dpy, CurrentTime);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,8 +365,7 @@ xev_handle_randr(XEvent *ee)
|
|||||||
TAILQ_FOREACH(sc, &Screenq, entry) {
|
TAILQ_FOREACH(sc, &Screenq, entry) {
|
||||||
if (sc->which == (u_int)i) {
|
if (sc->which == (u_int)i) {
|
||||||
XRRUpdateConfiguration(ee);
|
XRRUpdateConfiguration(ee);
|
||||||
screen_update_geometry(sc, rev->width, rev->height);
|
screen_update_geometry(sc);
|
||||||
screen_init_xinerama(sc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
238
xutil.c
238
xutil.c
@ -94,8 +94,8 @@ xu_key_grab(Window win, int mask, int keysym)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
code = XKeysymToKeycode(X_Dpy, keysym);
|
code = XKeysymToKeycode(X_Dpy, keysym);
|
||||||
if ((XKeycodeToKeysym(X_Dpy, code, 0) != keysym) &&
|
if ((XkbKeycodeToKeysym(X_Dpy, code, 0, 0) != keysym) &&
|
||||||
(XKeycodeToKeysym(X_Dpy, code, 1) == keysym))
|
(XkbKeycodeToKeysym(X_Dpy, code, 0, 1) == keysym))
|
||||||
mask |= ShiftMask;
|
mask |= ShiftMask;
|
||||||
|
|
||||||
for (i = 0; i < nitems(ign_mods); i++)
|
for (i = 0; i < nitems(ign_mods); i++)
|
||||||
@ -110,8 +110,8 @@ xu_key_ungrab(Window win, int mask, int keysym)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
code = XKeysymToKeycode(X_Dpy, keysym);
|
code = XKeysymToKeycode(X_Dpy, keysym);
|
||||||
if ((XKeycodeToKeysym(X_Dpy, code, 0) != keysym) &&
|
if ((XkbKeycodeToKeysym(X_Dpy, code, 0, 0) != keysym) &&
|
||||||
(XKeycodeToKeysym(X_Dpy, code, 1) == keysym))
|
(XkbKeycodeToKeysym(X_Dpy, code, 0, 1) == keysym))
|
||||||
mask |= ShiftMask;
|
mask |= ShiftMask;
|
||||||
|
|
||||||
for (i = 0; i < nitems(ign_mods); i++)
|
for (i = 0; i < nitems(ign_mods); i++)
|
||||||
@ -128,8 +128,8 @@ xu_configure(struct client_ctx *cc)
|
|||||||
ce.window = cc->win;
|
ce.window = cc->win;
|
||||||
ce.x = cc->geom.x;
|
ce.x = cc->geom.x;
|
||||||
ce.y = cc->geom.y;
|
ce.y = cc->geom.y;
|
||||||
ce.width = cc->geom.width;
|
ce.width = cc->geom.w;
|
||||||
ce.height = cc->geom.height;
|
ce.height = cc->geom.h;
|
||||||
ce.border_width = cc->bwidth;
|
ce.border_width = cc->bwidth;
|
||||||
ce.above = None;
|
ce.above = None;
|
||||||
ce.override_redirect = 0;
|
ce.override_redirect = 0;
|
||||||
@ -207,7 +207,8 @@ xu_getstate(struct client_ctx *cc, int *state)
|
|||||||
{
|
{
|
||||||
long *p = NULL;
|
long *p = NULL;
|
||||||
|
|
||||||
if (xu_getprop(cc->win, WM_STATE, WM_STATE, 2L, (u_char **)&p) <= 0)
|
if (xu_getprop(cc->win, cwmh[WM_STATE].atom, cwmh[WM_STATE].atom, 2L,
|
||||||
|
(u_char **)&p) <= 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
*state = (int)*p;
|
*state = (int)*p;
|
||||||
@ -225,63 +226,194 @@ xu_setstate(struct client_ctx *cc, int state)
|
|||||||
dat[1] = None;
|
dat[1] = None;
|
||||||
|
|
||||||
cc->state = state;
|
cc->state = state;
|
||||||
XChangeProperty(X_Dpy, cc->win, WM_STATE, WM_STATE, 32,
|
XChangeProperty(X_Dpy, cc->win,
|
||||||
|
cwmh[WM_STATE].atom, cwmh[WM_STATE].atom, 32,
|
||||||
PropModeReplace, (unsigned char *)dat, 2);
|
PropModeReplace, (unsigned char *)dat, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Atom cwm_atoms[CWM_NO_ATOMS];
|
struct atom_ctx cwmh[CWMH_NITEMS] = {
|
||||||
char *atoms[CWM_NO_ATOMS] = {
|
{"WM_STATE", None},
|
||||||
"WM_STATE",
|
{"WM_DELETE_WINDOW", None},
|
||||||
"WM_DELETE_WINDOW",
|
{"WM_TAKE_FOCUS", None},
|
||||||
"WM_TAKE_FOCUS",
|
{"WM_PROTOCOLS", None},
|
||||||
"WM_PROTOCOLS",
|
{"_MOTIF_WM_HINTS", None},
|
||||||
"_MOTIF_WM_HINTS",
|
{"UTF8_STRING", None},
|
||||||
"UTF8_STRING",
|
};
|
||||||
"_NET_SUPPORTED",
|
struct atom_ctx ewmh[EWMH_NITEMS] = {
|
||||||
"_NET_SUPPORTING_WM_CHECK",
|
{"_NET_SUPPORTED", None},
|
||||||
"_NET_WM_NAME",
|
{"_NET_SUPPORTING_WM_CHECK", None},
|
||||||
"_NET_ACTIVE_WINDOW",
|
{"_NET_ACTIVE_WINDOW", None},
|
||||||
"_NET_CLIENT_LIST",
|
{"_NET_CLIENT_LIST", None},
|
||||||
"_NET_NUMBER_OF_DESKTOPS",
|
{"_NET_NUMBER_OF_DESKTOPS", None},
|
||||||
"_NET_CURRENT_DESKTOP",
|
{"_NET_CURRENT_DESKTOP", None},
|
||||||
"_NET_DESKTOP_VIEWPORT",
|
{"_NET_DESKTOP_VIEWPORT", None},
|
||||||
"_NET_DESKTOP_GEOMETRY",
|
{"_NET_DESKTOP_GEOMETRY", None},
|
||||||
"_NET_VIRTUAL_ROOTS",
|
{"_NET_VIRTUAL_ROOTS", None},
|
||||||
"_NET_SHOWING_DESKTOP",
|
{"_NET_SHOWING_DESKTOP", None},
|
||||||
"_NET_DESKTOP_NAMES",
|
{"_NET_DESKTOP_NAMES", None},
|
||||||
"_NET_WM_DESKTOP",
|
{"_NET_WORKAREA", None},
|
||||||
"_NET_WORKAREA",
|
{"_NET_WM_NAME", None},
|
||||||
|
{"_NET_WM_DESKTOP", None},
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
xu_getatoms(void)
|
xu_getatoms(void)
|
||||||
{
|
{
|
||||||
XInternAtoms(X_Dpy, atoms, CWM_NO_ATOMS, False, cwm_atoms);
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < nitems(cwmh); i++)
|
||||||
|
cwmh[i].atom = XInternAtom(X_Dpy, cwmh[i].name, False);
|
||||||
|
for (i = 0; i < nitems(ewmh); i++)
|
||||||
|
ewmh[i].atom = XInternAtom(X_Dpy, ewmh[i].name, False);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Root Window Properties */
|
||||||
|
void
|
||||||
|
xu_ewmh_net_supported(struct screen_ctx *sc)
|
||||||
|
{
|
||||||
|
Atom atom[EWMH_NITEMS];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < nitems(ewmh); i++)
|
||||||
|
atom[i] = ewmh[i].atom;
|
||||||
|
|
||||||
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SUPPORTED].atom,
|
||||||
|
XA_ATOM, 32, PropModeReplace, (unsigned char *)atom, EWMH_NITEMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xu_setwmname(struct screen_ctx *sc)
|
xu_ewmh_net_supported_wm_check(struct screen_ctx *sc)
|
||||||
{
|
{
|
||||||
/*
|
Window w;
|
||||||
* set up the _NET_SUPPORTED hint with all netwm atoms that we
|
|
||||||
* know about.
|
w = XCreateSimpleWindow(X_Dpy, sc->rootwin, -1, -1, 1, 1, 0, 0, 0);
|
||||||
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SUPPORTING_WM_CHECK].atom,
|
||||||
|
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1);
|
||||||
|
XChangeProperty(X_Dpy, w, ewmh[_NET_SUPPORTING_WM_CHECK].atom,
|
||||||
|
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1);
|
||||||
|
XChangeProperty(X_Dpy, w, ewmh[_NET_WM_NAME].atom,
|
||||||
|
XA_WM_NAME, 8, PropModeReplace, WMNAME, strlen(WMNAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xu_ewmh_net_desktop_geometry(struct screen_ctx *sc)
|
||||||
|
{
|
||||||
|
long geom[2] = { sc->view.w, sc->view.h };
|
||||||
|
|
||||||
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_GEOMETRY].atom,
|
||||||
|
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)geom , 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xu_ewmh_net_workarea(struct screen_ctx *sc)
|
||||||
|
{
|
||||||
|
long workareas[CALMWM_NGROUPS][4];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < CALMWM_NGROUPS; i++) {
|
||||||
|
workareas[i][0] = sc->work.x;
|
||||||
|
workareas[i][1] = sc->work.y;
|
||||||
|
workareas[i][2] = sc->work.w;
|
||||||
|
workareas[i][3] = sc->work.h;
|
||||||
|
}
|
||||||
|
|
||||||
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_WORKAREA].atom,
|
||||||
|
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)workareas,
|
||||||
|
CALMWM_NGROUPS * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xu_ewmh_net_client_list(struct screen_ctx *sc)
|
||||||
|
{
|
||||||
|
struct client_ctx *cc;
|
||||||
|
Window *winlist;
|
||||||
|
int i = 0, j = 0;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(cc, &Clientq, entry)
|
||||||
|
i++;
|
||||||
|
if (i == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
winlist = xmalloc(i * sizeof(*winlist));
|
||||||
|
TAILQ_FOREACH(cc, &Clientq, entry)
|
||||||
|
winlist[j++] = cc->win;
|
||||||
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_CLIENT_LIST].atom,
|
||||||
|
XA_WINDOW, 32, PropModeReplace, (unsigned char *)winlist, i);
|
||||||
|
xfree(winlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xu_ewmh_net_active_window(struct screen_ctx *sc, Window w)
|
||||||
|
{
|
||||||
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_ACTIVE_WINDOW].atom,
|
||||||
|
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xu_ewmh_net_wm_desktop_viewport(struct screen_ctx *sc)
|
||||||
|
{
|
||||||
|
long viewports[2] = {0, 0};
|
||||||
|
|
||||||
|
/* We don't support large desktops, so this is (0, 0). */
|
||||||
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_VIEWPORT].atom,
|
||||||
|
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *sc)
|
||||||
|
{
|
||||||
|
long ndesks = CALMWM_NGROUPS;
|
||||||
|
|
||||||
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_NUMBER_OF_DESKTOPS].atom,
|
||||||
|
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&ndesks, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xu_ewmh_net_showing_desktop(struct screen_ctx *sc)
|
||||||
|
{
|
||||||
|
long zero = 0;
|
||||||
|
|
||||||
|
/* We don't support `showing desktop' mode, so this is zero.
|
||||||
|
* Note that when we hide all groups, or when all groups are
|
||||||
|
* hidden we could technically set this later on.
|
||||||
*/
|
*/
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, _NET_SUPPORTED, XA_ATOM, 32,
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SHOWING_DESKTOP].atom,
|
||||||
PropModeReplace, (unsigned char *)&_NET_SUPPORTED,
|
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&zero, 1);
|
||||||
CWM_NO_ATOMS - CWM_NETWM_START);
|
}
|
||||||
/*
|
|
||||||
* netwm spec says that to prove that the hint is not stale you must
|
void
|
||||||
* provide _NET_SUPPORTING_WM_CHECK containing a window (we use the
|
xu_ewmh_net_virtual_roots(struct screen_ctx *sc)
|
||||||
* menu window). The property must be set on the root window and the
|
{
|
||||||
* window itself, the window also must have _NET_WM_NAME set with the
|
/* We don't support virtual roots, so delete if set by previous wm. */
|
||||||
* window manager name.
|
XDeleteProperty(X_Dpy, sc->rootwin, ewmh[_NET_VIRTUAL_ROOTS].atom);
|
||||||
*/
|
}
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, _NET_SUPPORTING_WM_CHECK,
|
|
||||||
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&sc->menuwin, 1);
|
void
|
||||||
XChangeProperty(X_Dpy, sc->menuwin, _NET_SUPPORTING_WM_CHECK,
|
xu_ewmh_net_current_desktop(struct screen_ctx *sc, long idx)
|
||||||
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&sc->menuwin, 1);
|
{
|
||||||
XChangeProperty(X_Dpy, sc->menuwin, _NET_WM_NAME, UTF8_STRING,
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_CURRENT_DESKTOP].atom,
|
||||||
8, PropModeReplace, WMNAME, strlen(WMNAME));
|
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&idx, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xu_ewmh_net_desktop_names(struct screen_ctx *sc, unsigned char *data, int n)
|
||||||
|
{
|
||||||
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_NAMES].atom,
|
||||||
|
cwmh[UTF8_STRING].atom, 8, PropModeReplace, data, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Application Window Properties */
|
||||||
|
void
|
||||||
|
xu_ewmh_net_wm_desktop(struct client_ctx *cc)
|
||||||
|
{
|
||||||
|
struct group_ctx *gc = cc->group;
|
||||||
|
long no = 0xffffffff;
|
||||||
|
|
||||||
|
if (gc)
|
||||||
|
no = gc->shortcut - 1;
|
||||||
|
|
||||||
|
XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_DESKTOP].atom,
|
||||||
|
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&no, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
@ -292,10 +424,10 @@ xu_getcolor(struct screen_ctx *sc, char *name)
|
|||||||
if (!XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, sc->which),
|
if (!XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, sc->which),
|
||||||
name, &color, &tmp)) {
|
name, &color, &tmp)) {
|
||||||
warnx("XAllocNamedColor error: '%s'", name);
|
warnx("XAllocNamedColor error: '%s'", name);
|
||||||
return 0;
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return color.pixel;
|
return (color.pixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Reference in New Issue
Block a user