cvsimport

* refs/heads/master: (23 commits)
  Check the atom type on propertynotify before iterating.
  use screen_find() for xrandr crtc changes
  Find the managed screen from the parent window for client_current().
  Print window id in hex; while here, remove unnecessary newline.
  Similar to keypress event, fetch the screen from the event root window in the buttonpress handler; bail if we don't manage the screen. Allows us to find the current client based on the screen/event root.
  extend verbose logging for key/button events
  [keypress event] turns out we've been checking the wrong window for a matching client thus always falling back to client_current(); while the current client is problaby right in most cases, use event's subwindow (not window) to find the client. Bail early if this event came to us from a screen we don't manage. This is result of us grabing all keybindings off the root window instead of selectively.
  add parans for readibility
  Teach client_current() to use a screen to find the current client instead of iterating over all (fallback if no screen provided for now). Initially convert trivial uses of client_current().
  check cc->gc directly
  zip extra lines
  gc clientq inside groups, instead use the better maintained one per-screen
  shuffle deck chairs: rename group actions to match intent for clarity
  same thing as screen_find()
  Separate out the menu window from the client resize/move geom window; in each case, create and destroy on-demand. Isolate more menu specific code.
  fix a few misplaced (and misnamed) ewmh root window functions
  _NET_WORKAREA needs ngroups, so screen_update_geometry() needs to come after conf_group().
  simplify xftcolor config
  Tie group number and name together during config.
  Move the group index (desktop number) check to the only 2 callers that require checking due to ewmh.
  ...
This commit is contained in:
okan 2019-03-11 15:25:46 +00:00
commit 85d88f3304
11 changed files with 321 additions and 285 deletions

View File

@ -55,7 +55,7 @@ main(int argc, char **argv)
{
char *display_name = NULL;
char *fallback;
int ch, xfd;
int ch, xfd, nflag = 0;
struct pollfd pfd[1];
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
@ -66,7 +66,7 @@ main(int argc, char **argv)
fallback = u_argv(argv);
Conf.wm_argv = u_argv(argv);
while ((ch = getopt(argc, argv, "c:d:v")) != -1) {
while ((ch = getopt(argc, argv, "c:d:nv")) != -1) {
switch (ch) {
case 'c':
free(Conf.conf_file);
@ -75,6 +75,9 @@ main(int argc, char **argv)
case 'd':
display_name = optarg;
break;
case 'n':
nflag = 1;
break;
case 'v':
Conf.debug++;
break;
@ -90,8 +93,13 @@ main(int argc, char **argv)
if (signal(SIGHUP, sighdlr) == SIG_ERR)
err(1, "signal");
if (parse_config(Conf.conf_file, &Conf) == -1)
if (parse_config(Conf.conf_file, &Conf) == -1) {
warnx("error parsing config file");
if (nflag)
return 1;
}
if (nflag)
return 0;
xfd = x_init(display_name);
cwm_status = CWM_RUNNING;
@ -159,8 +167,6 @@ x_teardown(void)
DefaultColormap(X_Dpy, sc->which),
&sc->xftcolor[i]);
XftFontClose(X_Dpy, sc->xftfont);
XftDrawDestroy(sc->menu.xftdraw);
XDestroyWindow(X_Dpy, sc->menu.win);
XUngrabKey(X_Dpy, AnyKey, AnyModifier, sc->rootwin);
}
XUngrabPointer(X_Dpy, CurrentTime);
@ -221,7 +227,7 @@ usage(void)
{
extern char *__progname;
(void)fprintf(stderr, "usage: %s [-v] [-c file] [-d display]\n",
(void)fprintf(stderr, "usage: %s [-nv] [-c file] [-d display]\n",
__progname);
exit(1);
}

View File

@ -68,9 +68,6 @@ size_t strlcpy(char *, const char *, size_t);
#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask)
#define MOUSEMASK (BUTTONMASK | PointerMotionMask)
#define MENUMASK (MOUSEMASK | ButtonMotionMask | KeyPressMask | \
ExposureMask)
#define MENUGRABMASK (MOUSEMASK | ButtonMotionMask | StructureNotifyMask)
#define IGNOREMODMASK (LockMask | Mod2Mask | 0x2000)
/* direction/amount */
@ -145,7 +142,6 @@ TAILQ_HEAD(ignore_q, winname);
struct client_ctx {
TAILQ_ENTRY(client_ctx) entry;
TAILQ_ENTRY(client_ctx) group_entry;
struct screen_ctx *sc;
struct group_ctx *gc;
Window win;
@ -211,7 +207,6 @@ struct group_ctx {
struct screen_ctx *sc;
char *name;
int num;
struct client_q clientq;
};
TAILQ_HEAD(group_q, group_ctx);
@ -250,7 +245,7 @@ struct screen_ctx {
struct {
Window win;
XftDraw *xftdraw;
} menu;
} prop;
XftColor xftcolor[CWM_COLOR_NITEMS];
XftFont *xftfont;
};
@ -420,7 +415,7 @@ void usage(void);
void client_applysizehints(struct client_ctx *);
void client_config(struct client_ctx *);
struct client_ctx *client_current(void);
struct client_ctx *client_current(struct screen_ctx *);
void client_cycle(struct screen_ctx *, int);
void client_remove(struct client_ctx *);
void client_draw_border(struct client_ctx *);
@ -456,25 +451,24 @@ void client_toggle_skip_taskbar(struct client_ctx *);
void client_toggle_sticky(struct client_ctx *);
void client_toggle_vmaximize(struct client_ctx *);
void client_transient(struct client_ctx *);
void client_unhide(struct client_ctx *);
void client_urgency(struct client_ctx *);
void client_vtile(struct client_ctx *);
void client_wm_hints(struct client_ctx *);
void group_alltoggle(struct screen_ctx *);
void group_assign(struct group_ctx *, struct client_ctx *);
int group_autogroup(struct client_ctx *);
void group_cycle(struct screen_ctx *, int);
void group_hide(struct group_ctx *);
void group_hidetoggle(struct screen_ctx *, int);
int group_holds_only_hidden(struct group_ctx *);
int group_holds_only_sticky(struct group_ctx *);
void group_init(struct screen_ctx *, int);
void group_init(struct screen_ctx *, int, const char *);
void group_movetogroup(struct client_ctx *, int);
void group_only(struct screen_ctx *, int);
void group_close(struct screen_ctx *, int);
int group_restore(struct client_ctx *);
void group_show(struct group_ctx *);
void group_toggle(struct screen_ctx *, int);
void group_toggle_all(struct screen_ctx *);
void group_toggle_membership(struct client_ctx *);
void group_update_names(struct screen_ctx *);
@ -506,6 +500,12 @@ void screen_init(int);
void screen_update_geometry(struct screen_ctx *);
void screen_updatestackingorder(struct screen_ctx *);
void screen_assert_clients_within(struct screen_ctx *);
void screen_prop_win_create(struct screen_ctx *, Window);
void screen_prop_win_destroy(struct screen_ctx *);
void screen_prop_win_draw(struct screen_ctx *,
const char *, ...)
__attribute__((__format__ (printf, 2, 3)))
__attribute__((__nonnull__ (2)));
void kbfunc_cwm_status(void *, struct cargs *);
void kbfunc_ptrmove(void *, struct cargs *);
@ -532,7 +532,7 @@ void kbfunc_group_toggle(void *, struct cargs *);
void kbfunc_group_only(void *, struct cargs *);
void kbfunc_group_close(void *, struct cargs *);
void kbfunc_group_cycle(void *, struct cargs *);
void kbfunc_group_alltoggle(void *, struct cargs *);
void kbfunc_group_toggle_all(void *, struct cargs *);
void kbfunc_menu_client(void *, struct cargs *);
void kbfunc_menu_cmd(void *, struct cargs *);
void kbfunc_menu_group(void *, struct cargs *);
@ -544,10 +544,6 @@ void kbfunc_exec_cmd(void *, struct cargs *);
void kbfunc_exec_lock(void *, struct cargs *);
void kbfunc_exec_term(void *, struct cargs *);
void menu_windraw(struct screen_ctx *, Window,
const char *, ...)
__attribute__((__format__ (printf, 3, 4)))
__attribute__((__nonnull__ (3)));
struct menu *menu_filter(struct screen_ctx *, struct menu_q *,
const char *, const char *, int,
void (*)(struct menu_q *, struct menu_q *, char *),
@ -577,6 +573,7 @@ void conf_grab_mouse(Window);
void conf_init(struct conf *);
void conf_ignore(struct conf *, const char *);
void conf_screen(struct screen_ctx *);
void conf_group(struct screen_ctx *);
void xev_process(void);
@ -589,13 +586,13 @@ void xu_xorcolor(XftColor, XftColor, XftColor *);
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_desktop_viewport(struct screen_ctx *);
void xu_ewmh_net_workarea(struct screen_ctx *);
void xu_ewmh_net_client_list(struct screen_ctx *);
void xu_ewmh_net_client_list_stacking(struct screen_ctx *);
void xu_ewmh_net_active_window(struct screen_ctx *, Window);
Window xu_ewmh_get_net_active_window(struct screen_ctx *);
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_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 *);

View File

@ -128,7 +128,7 @@ client_init(Window win, struct screen_ctx *sc, int active)
if (client_get_wm_state(cc) == IconicState)
client_hide(cc);
else
client_unhide(cc);
client_show(cc);
if (mapped) {
if (cc->gc) {
@ -183,9 +183,6 @@ client_remove(struct client_ctx *cc)
if (cc->flags & CLIENT_ACTIVE)
xu_ewmh_net_active_window(sc, None);
if (cc->gc != NULL)
TAILQ_REMOVE(&cc->gc->clientq, cc, group_entry);
while ((wn = TAILQ_FIRST(&cc->nameq)) != NULL) {
TAILQ_REMOVE(&cc->nameq, wn, entry);
free(wn->name);
@ -221,7 +218,7 @@ client_setactive(struct client_ctx *cc)
if (cc->flags & CLIENT_WM_TAKE_FOCUS)
client_msg(cc, cwmh[WM_TAKE_FOCUS], Last_Event_Time);
if ((oldcc = client_current()) != NULL) {
if ((oldcc = client_current(sc)) != NULL) {
oldcc->flags &= ~CLIENT_ACTIVE;
client_draw_border(oldcc);
}
@ -238,16 +235,23 @@ client_setactive(struct client_ctx *cc)
}
struct client_ctx *
client_current(void)
client_current(struct screen_ctx *sc)
{
struct screen_ctx *sc;
struct screen_ctx *_sc;
struct client_ctx *cc;
TAILQ_FOREACH(sc, &Screenq, entry) {
if (sc) {
TAILQ_FOREACH(cc, &sc->clientq, entry) {
if (cc->flags & CLIENT_ACTIVE)
return(cc);
}
} else {
TAILQ_FOREACH(_sc, &Screenq, entry) {
TAILQ_FOREACH(cc, &_sc->clientq, entry) {
if (cc->flags & CLIENT_ACTIVE)
return(cc);
}
}
}
return(NULL);
}
@ -527,25 +531,16 @@ client_hide(struct client_ctx *cc)
{
XUnmapWindow(X_Dpy, cc->win);
if (cc->flags & CLIENT_ACTIVE)
if (cc->flags & CLIENT_ACTIVE) {
cc->flags &= ~CLIENT_ACTIVE;
xu_ewmh_net_active_window(cc->sc, None);
cc->flags &= ~CLIENT_ACTIVE;
}
cc->flags |= CLIENT_HIDDEN;
client_set_wm_state(cc, IconicState);
}
void
client_show(struct client_ctx *cc)
{
if (cc->flags & CLIENT_HIDDEN)
client_unhide(cc);
else
client_raise(cc);
}
void
client_unhide(struct client_ctx *cc)
{
XMapRaised(X_Dpy, cc->win);
@ -691,7 +686,7 @@ client_cycle(struct screen_ctx *sc, int flags)
return;
prevcc = TAILQ_FIRST(&sc->clientq);
oldcc = client_current();
oldcc = client_current(sc);
if (oldcc == NULL)
oldcc = (flags & CWM_CYCLE_REVERSE) ?
TAILQ_LAST(&sc->clientq, client_q) :
@ -972,12 +967,11 @@ void
client_htile(struct client_ctx *cc)
{
struct client_ctx *ci;
struct group_ctx *gc = cc->gc;
struct screen_ctx *sc = cc->sc;
struct geom area;
int i, n, mh, x, w, h;
if (!gc)
if (!cc->gc)
return;
i = n = 0;
@ -985,7 +979,9 @@ client_htile(struct client_ctx *cc)
cc->geom.x + cc->geom.w / 2,
cc->geom.y + cc->geom.h / 2, CWM_GAP);
TAILQ_FOREACH(ci, &gc->clientq, group_entry) {
TAILQ_FOREACH(ci, &sc->clientq, entry) {
if (ci->gc != cc->gc)
continue;
if (ci->flags & CLIENT_HIDDEN ||
ci->flags & CLIENT_IGNORE || (ci == cc) ||
ci->geom.x < area.x ||
@ -1014,7 +1010,9 @@ client_htile(struct client_ctx *cc)
x = area.x;
w = area.w / n;
h = area.h - mh;
TAILQ_FOREACH(ci, &gc->clientq, group_entry) {
TAILQ_FOREACH(ci, &sc->clientq, entry) {
if (ci->gc != cc->gc)
continue;
if (ci->flags & CLIENT_HIDDEN ||
ci->flags & CLIENT_IGNORE || (ci == cc) ||
ci->geom.x < area.x ||
@ -1040,12 +1038,11 @@ void
client_vtile(struct client_ctx *cc)
{
struct client_ctx *ci;
struct group_ctx *gc = cc->gc;
struct screen_ctx *sc = cc->sc;
struct geom area;
int i, n, mw, y, w, h;
if (!gc)
if (!cc->gc)
return;
i = n = 0;
@ -1053,7 +1050,9 @@ client_vtile(struct client_ctx *cc)
cc->geom.x + cc->geom.w / 2,
cc->geom.y + cc->geom.h / 2, CWM_GAP);
TAILQ_FOREACH(ci, &gc->clientq, group_entry) {
TAILQ_FOREACH(ci, &sc->clientq, entry) {
if (ci->gc != cc->gc)
continue;
if (ci->flags & CLIENT_HIDDEN ||
ci->flags & CLIENT_IGNORE || (ci == cc) ||
ci->geom.x < area.x ||
@ -1082,7 +1081,9 @@ client_vtile(struct client_ctx *cc)
y = area.y;
h = area.h / n;
w = area.w - mw;
TAILQ_FOREACH(ci, &gc->clientq, group_entry) {
TAILQ_FOREACH(ci, &sc->clientq, entry) {
if (ci->gc != cc->gc)
continue;
if (ci->flags & CLIENT_HIDDEN ||
ci->flags & CLIENT_IGNORE || (ci == cc) ||
ci->geom.x < area.x ||

47
conf.c
View File

@ -36,6 +36,21 @@ static const char *conf_bind_getmask(const char *, unsigned int *);
static void conf_unbind_key(struct conf *, struct bind_ctx *);
static void conf_unbind_mouse(struct conf *, struct bind_ctx *);
static const struct {
int num;
const char *name;
} group_binds[] = {
{ 0, "nogroup" },
{ 1, "one" },
{ 2, "two" },
{ 3, "three" },
{ 4, "four" },
{ 5, "five" },
{ 6, "six" },
{ 7, "seven" },
{ 8, "eight" },
{ 9, "nine" },
};
static int cursor_binds[] = {
XC_left_ptr, /* CF_NORMAL */
XC_fleur, /* CF_MOVE */
@ -124,7 +139,7 @@ static const struct {
{ FUNC_SC(group-cycle, group_cycle, (CWM_CYCLE_FORWARD)) },
{ FUNC_SC(group-rcycle, group_cycle, (CWM_CYCLE_REVERSE)) },
{ FUNC_SC(group-toggle-all, group_alltoggle, 0) },
{ FUNC_SC(group-toggle-all, group_toggle_all, 0) },
{ FUNC_SC(group-toggle-1, group_toggle, 1) },
{ FUNC_SC(group-toggle-2, group_toggle, 2) },
{ FUNC_SC(group-toggle-3, group_toggle, 3) },
@ -266,7 +281,7 @@ conf_init(struct conf *c)
c->bwidth = 1;
c->mamount = 1;
c->snapdist = 0;
c->ngroups = 10;
c->ngroups = 0;
c->nameqlen = 5;
TAILQ_INIT(&c->ignoreq);
@ -478,30 +493,28 @@ conf_screen(struct screen_ctx *sc)
warnx("XftColorAllocValue: %s", Conf.color[i]);
break;
}
if (XftColorAllocName(X_Dpy, sc->visual, sc->colormap,
Conf.color[i], &xc)) {
sc->xftcolor[i] = xc;
XftColorFree(X_Dpy, sc->visual, sc->colormap, &xc);
} else {
if (!XftColorAllocName(X_Dpy, sc->visual, sc->colormap,
Conf.color[i], &sc->xftcolor[i])) {
warnx("XftColorAllocName: %s", Conf.color[i]);
XftColorAllocName(X_Dpy, sc->visual, sc->colormap,
color_binds[i], &sc->xftcolor[i]);
}
}
sc->menu.win = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1,
Conf.bwidth,
sc->xftcolor[CWM_COLOR_MENU_FG].pixel,
sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
sc->menu.xftdraw = XftDrawCreate(X_Dpy, sc->menu.win,
sc->visual, sc->colormap);
if (sc->menu.xftdraw == NULL)
errx(1, "%s: XftDrawCreate", __func__);
conf_grab_kbd(sc->rootwin);
}
void
conf_group(struct screen_ctx *sc)
{
unsigned int i;
for (i = 0; i < nitems(group_binds); i++) {
group_init(sc, group_binds[i].num, group_binds[i].name);
Conf.ngroups++;
}
}
static const char *
conf_bind_getmask(const char *name, unsigned int *mask)
{

5
cwm.1
View File

@ -23,7 +23,7 @@
.Sh SYNOPSIS
.\" For a program: program [-abc] file ...
.Nm cwm
.Op Fl v
.Op Fl nv
.Op Fl c Ar file
.Op Fl d Ar display
.Sh DESCRIPTION
@ -48,6 +48,9 @@ however,
will continue to process the rest of the configuration file.
.It Fl d Ar display
Specify the display to use.
.It Fl n
Configtest mode.
Only check the configuration file for validity.
.It Fl v
Verbose mode.
Multiple

154
group.c
View File

@ -37,37 +37,30 @@ static struct group_ctx *group_prev(struct group_ctx *);
static void group_restack(struct group_ctx *);
static void group_setactive(struct group_ctx *);
const char *num_to_name[] = {
"nogroup", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine"
};
void
group_assign(struct group_ctx *gc, struct client_ctx *cc)
{
if (cc->gc != NULL)
TAILQ_REMOVE(&cc->gc->clientq, cc, group_entry);
if ((gc != NULL) && (gc->num == 0))
gc = NULL;
cc->gc = gc;
if (cc->gc != NULL)
TAILQ_INSERT_TAIL(&gc->clientq, cc, group_entry);
xu_ewmh_net_wm_desktop(cc);
}
void
group_hide(struct group_ctx *gc)
{
struct screen_ctx *sc = gc->sc;
struct client_ctx *cc;
screen_updatestackingorder(gc->sc);
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
if (!(cc->flags & CLIENT_STICKY))
TAILQ_FOREACH(cc, &sc->clientq, entry) {
if (cc->gc != gc)
continue;
if (!(cc->flags & CLIENT_STICKY) &&
!(cc->flags & CLIENT_HIDDEN))
client_hide(cc);
}
}
@ -75,13 +68,16 @@ group_hide(struct group_ctx *gc)
void
group_show(struct group_ctx *gc)
{
struct screen_ctx *sc = gc->sc;
struct client_ctx *cc;
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
if (!(cc->flags & CLIENT_STICKY))
client_unhide(cc);
TAILQ_FOREACH(cc, &sc->clientq, entry) {
if (cc->gc != gc)
continue;
if (!(cc->flags & CLIENT_STICKY) &&
(cc->flags & CLIENT_HIDDEN))
client_show(cc);
}
group_restack(gc);
group_setactive(gc);
}
@ -89,19 +85,24 @@ group_show(struct group_ctx *gc)
static void
group_restack(struct group_ctx *gc)
{
struct screen_ctx *sc = gc->sc;
struct client_ctx *cc;
Window *winlist;
int i, lastempty = -1;
int nwins = 0, highstack = 0;
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
TAILQ_FOREACH(cc, &sc->clientq, entry) {
if (cc->gc != gc)
continue;
if (cc->stackingorder > highstack)
highstack = cc->stackingorder;
}
winlist = xreallocarray(NULL, (highstack + 1), sizeof(*winlist));
/* Invert the stacking order for XRestackWindows(). */
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
TAILQ_FOREACH(cc, &sc->clientq, entry) {
if (cc->gc != gc)
continue;
winlist[highstack - cc->stackingorder] = cc->win;
nwins++;
}
@ -122,16 +123,14 @@ group_restack(struct group_ctx *gc)
}
void
group_init(struct screen_ctx *sc, int num)
group_init(struct screen_ctx *sc, int num, const char *name)
{
struct group_ctx *gc;
gc = xmalloc(sizeof(*gc));
gc->sc = sc;
gc->name = xstrdup(num_to_name[num]);
gc->name = xstrdup(name);
gc->num = num;
TAILQ_INIT(&gc->clientq);
TAILQ_INSERT_TAIL(&sc->groupq, gc, entry);
if (num == 1)
@ -154,19 +153,15 @@ group_movetogroup(struct client_ctx *cc, int idx)
struct screen_ctx *sc = cc->sc;
struct group_ctx *gc;
if (idx < 0 || idx >= Conf.ngroups)
return;
TAILQ_FOREACH(gc, &sc->groupq, entry) {
if (gc->num == idx)
break;
if (gc->num == idx) {
if (cc->gc == gc)
return;
if (gc->num != 0 && group_holds_only_hidden(gc))
client_hide(cc);
group_assign(gc, cc);
}
}
if (cc->gc == gc)
return;
if (gc->num != 0 && group_holds_only_hidden(gc))
client_hide(cc);
group_assign(gc, cc);
}
void
@ -175,23 +170,25 @@ group_toggle_membership(struct client_ctx *cc)
struct screen_ctx *sc = cc->sc;
struct group_ctx *gc = sc->group_active;
if (gc == cc->gc) {
if (cc->gc == gc) {
group_assign(NULL, cc);
cc->flags |= CLIENT_UNGROUP;
} else {
group_assign(gc, cc);
cc->flags |= CLIENT_GROUP;
}
client_draw_border(cc);
}
int
group_holds_only_sticky(struct group_ctx *gc)
{
struct screen_ctx *sc = gc->sc;
struct client_ctx *cc;
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
TAILQ_FOREACH(cc, &sc->clientq, entry) {
if (cc->gc != gc)
continue;
if (!(cc->flags & CLIENT_STICKY))
return(0);
}
@ -201,46 +198,23 @@ group_holds_only_sticky(struct group_ctx *gc)
int
group_holds_only_hidden(struct group_ctx *gc)
{
struct screen_ctx *sc = gc->sc;
struct client_ctx *cc;
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
TAILQ_FOREACH(cc, &sc->clientq, entry) {
if (cc->gc != gc)
continue;
if (!(cc->flags & (CLIENT_HIDDEN | CLIENT_STICKY)))
return(0);
}
return(1);
}
void
group_hidetoggle(struct screen_ctx *sc, int idx)
{
struct group_ctx *gc;
if (idx < 0 || idx >= Conf.ngroups)
return;
TAILQ_FOREACH(gc, &sc->groupq, entry) {
if (gc->num == idx)
break;
}
if (group_holds_only_hidden(gc))
group_show(gc);
else {
group_hide(gc);
/* make clients stick to empty group */
if (TAILQ_EMPTY(&gc->clientq))
group_setactive(gc);
}
}
void
group_only(struct screen_ctx *sc, int idx)
{
struct group_ctx *gc;
if (idx < 0 || idx >= Conf.ngroups)
return;
TAILQ_FOREACH(gc, &sc->groupq, entry) {
if (gc->num == idx)
group_show(gc);
@ -249,19 +223,48 @@ group_only(struct screen_ctx *sc, int idx)
}
}
void
group_toggle(struct screen_ctx *sc, int idx)
{
struct group_ctx *gc;
TAILQ_FOREACH(gc, &sc->groupq, entry) {
if (gc->num == idx) {
if (group_holds_only_hidden(gc))
group_show(gc);
else
group_hide(gc);
}
}
}
void
group_toggle_all(struct screen_ctx *sc)
{
struct group_ctx *gc;
TAILQ_FOREACH(gc, &sc->groupq, entry) {
if (sc->hideall)
group_show(gc);
else
group_hide(gc);
}
sc->hideall = !sc->hideall;
}
void
group_close(struct screen_ctx *sc, int idx)
{
struct group_ctx *gc;
struct client_ctx *cc;
if (idx < 0 || idx >= Conf.ngroups)
return;
TAILQ_FOREACH(gc, &sc->groupq, entry) {
if (gc->num == idx) {
TAILQ_FOREACH(cc, &gc->clientq, group_entry)
TAILQ_FOREACH(cc, &sc->clientq, entry) {
if (cc->gc != gc)
continue;
client_close(cc);
}
}
}
}
@ -286,7 +289,6 @@ group_cycle(struct screen_ctx *sc, int flags)
else if (!group_holds_only_hidden(newgc))
group_hide(newgc);
}
if (showgroup == NULL)
return;
@ -318,20 +320,6 @@ group_prev(struct group_ctx *gc)
newgc : TAILQ_LAST(&sc->groupq, group_q));
}
void
group_alltoggle(struct screen_ctx *sc)
{
struct group_ctx *gc;
TAILQ_FOREACH(gc, &sc->groupq, entry) {
if (sc->hideall)
group_show(gc);
else
group_hide(gc);
}
sc->hideall = !sc->hideall;
}
int
group_restore(struct client_ctx *cc)
{

View File

@ -169,8 +169,8 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs)
CurrentTime) != GrabSuccess)
return;
menu_windraw(sc, cc->win, "%4d, %-4d", cc->geom.x, cc->geom.y);
screen_prop_win_create(sc, cc->win);
screen_prop_win_draw(sc, "%+5d%+5d", cc->geom.x, cc->geom.y);
while (move) {
XMaskEvent(X_Dpy, MOUSEMASK, &ev);
switch (ev.type) {
@ -193,8 +193,8 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs)
cc->geom.y + cc->geom.h + (cc->bwidth * 2),
area.y, area.y + area.h, sc->snapdist);
client_move(cc);
menu_windraw(sc, cc->win,
"%4d, %-4d", cc->geom.x, cc->geom.y);
screen_prop_win_draw(sc,
"%+5d%+5d", cc->geom.x, cc->geom.y);
break;
case ButtonRelease:
move = 0;
@ -203,8 +203,7 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs)
}
if (ltime)
client_move(cc);
XUnmapWindow(X_Dpy, sc->menu.win);
XReparentWindow(X_Dpy, sc->menu.win, sc->rootwin, 0, 0);
screen_prop_win_destroy(sc);
XUngrabPointer(X_Dpy, CurrentTime);
}
@ -258,7 +257,8 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
CurrentTime) != GrabSuccess)
return;
menu_windraw(sc, cc->win, "%4d x %-4d", cc->dim.w, cc->dim.h);
screen_prop_win_create(sc, cc->win);
screen_prop_win_draw(sc, "%4d x %-4d", cc->dim.w, cc->dim.h);
while (resize) {
XMaskEvent(X_Dpy, MOUSEMASK, &ev);
switch (ev.type) {
@ -272,7 +272,7 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
cc->geom.h = ev.xmotion.y;
client_applysizehints(cc);
client_resize(cc, 1);
menu_windraw(sc, cc->win,
screen_prop_win_draw(sc,
"%4d x %-4d", cc->dim.w, cc->dim.h);
break;
case ButtonRelease:
@ -282,8 +282,7 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
}
if (ltime)
client_resize(cc, 1);
XUnmapWindow(X_Dpy, sc->menu.win);
XReparentWindow(X_Dpy, sc->menu.win, sc->rootwin, 0, 0);
screen_prop_win_destroy(sc);
XUngrabPointer(X_Dpy, CurrentTime);
/* Make sure the pointer stays within the window. */
@ -431,18 +430,24 @@ kbfunc_client_movetogroup(void *ctx, struct cargs *cargs)
group_movetogroup(ctx, cargs->flag);
}
void
kbfunc_group_toggle(void *ctx, struct cargs *cargs)
{
group_hidetoggle(ctx, cargs->flag);
}
void
kbfunc_group_only(void *ctx, struct cargs *cargs)
{
group_only(ctx, cargs->flag);
}
void
kbfunc_group_toggle(void *ctx, struct cargs *cargs)
{
group_toggle(ctx, cargs->flag);
}
void
kbfunc_group_toggle_all(void *ctx, struct cargs *cargs)
{
group_toggle_all(ctx);
}
void
kbfunc_group_close(void *ctx, struct cargs *cargs)
{
@ -455,12 +460,6 @@ kbfunc_group_cycle(void *ctx, struct cargs *cargs)
group_cycle(ctx, cargs->flag);
}
void
kbfunc_group_alltoggle(void *ctx, struct cargs *cargs)
{
group_alltoggle(ctx);
}
void
kbfunc_menu_client(void *ctx, struct cargs *cargs)
{
@ -474,7 +473,7 @@ kbfunc_menu_client(void *ctx, struct cargs *cargs)
if (cargs->xev == CWM_XEV_BTN)
mflags |= CWM_MENU_LIST;
old_cc = client_current();
old_cc = client_current(sc);
TAILQ_INIT(&menuq);
TAILQ_FOREACH(cc, &sc->clientq, entry) {

82
menu.c
View File

@ -37,6 +37,10 @@
#define PROMPT_SCHAR "\xc2\xbb"
#define PROMPT_ECHAR "\xc2\xab"
#define MENUMASK (MOUSEMASK | ButtonMotionMask | KeyPressMask | \
ExposureMask)
#define MENUGRABMASK (MOUSEMASK | ButtonMotionMask | StructureNotifyMask)
enum ctltype {
CTL_NONE = -1,
CTL_ERASEONE = 0, CTL_WIPE, CTL_UP, CTL_DOWN, CTL_RETURN,
@ -45,6 +49,9 @@ enum ctltype {
struct menu_ctx {
struct screen_ctx *sc;
Window win;
XftDraw *xftdraw;
struct geom geom;
char searchstr[MENU_MAXENTRY + 1];
char dispstr[MENU_MAXENTRY*2 + 1];
char promptstr[MENU_MAXENTRY + 1];
@ -55,7 +62,6 @@ struct menu_ctx {
int entry;
int num;
int flags;
struct geom geom;
void (*match)(struct menu_q *, struct menu_q *, char *);
void (*print)(struct menu *, int);
};
@ -108,27 +114,34 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, const char *prompt,
else
mc.searchstr[0] = '\0';
XSelectInput(X_Dpy, sc->menu.win, MENUMASK);
XMapRaised(X_Dpy, sc->menu.win);
mc.win = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1,
Conf.bwidth,
sc->xftcolor[CWM_COLOR_MENU_FG].pixel,
sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
mc.xftdraw = XftDrawCreate(X_Dpy, mc.win,
sc->visual, sc->colormap);
if (XGrabPointer(X_Dpy, sc->menu.win, False, MENUGRABMASK,
XSelectInput(X_Dpy, mc.win, MENUMASK);
XMapRaised(X_Dpy, mc.win);
if (XGrabPointer(X_Dpy, mc.win, False, MENUGRABMASK,
GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_QUESTION],
CurrentTime) != GrabSuccess) {
XUnmapWindow(X_Dpy, sc->menu.win);
return(NULL);
XftDrawDestroy(mc.xftdraw);
XDestroyWindow(X_Dpy, mc.win);
}
XGetInputFocus(X_Dpy, &focuswin, &focusrevert);
XSetInputFocus(X_Dpy, sc->menu.win, RevertToPointerRoot, CurrentTime);
XSetInputFocus(X_Dpy, mc.win, RevertToPointerRoot, CurrentTime);
/* make sure keybindings don't remove keys from the menu stream */
XGrabKeyboard(X_Dpy, sc->menu.win, True,
XGrabKeyboard(X_Dpy, mc.win, True,
GrabModeAsync, GrabModeAsync, CurrentTime);
for (;;) {
mc.changed = 0;
XWindowEvent(X_Dpy, sc->menu.win, MENUMASK, &e);
XWindowEvent(X_Dpy, mc.win, MENUMASK, &e);
switch (e.type) {
case KeyPress:
@ -159,16 +172,16 @@ out:
mi = NULL;
}
XSelectInput(X_Dpy, sc->menu.win, NoEventMask);
XftDrawDestroy(mc.xftdraw);
XDestroyWindow(X_Dpy, mc.win);
XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime);
/* restore if user didn't move */
xu_ptr_getpos(sc->rootwin, &xcur, &ycur);
if (xcur == mc.geom.x && ycur == mc.geom.y)
xu_ptr_setpos(sc->rootwin, xsave, ysave);
XUngrabPointer(X_Dpy, CurrentTime);
XMoveResizeWindow(X_Dpy, sc->menu.win, 0, 0, 1, 1);
XUnmapWindow(X_Dpy, sc->menu.win);
XUngrabPointer(X_Dpy, CurrentTime);
XUngrabKeyboard(X_Dpy, CurrentTime);
return(mi);
@ -378,12 +391,12 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
if (mc->geom.x != xsave || mc->geom.y != ysave)
xu_ptr_setpos(sc->rootwin, mc->geom.x, mc->geom.y);
XClearWindow(X_Dpy, sc->menu.win);
XMoveResizeWindow(X_Dpy, sc->menu.win, mc->geom.x, mc->geom.y,
XClearWindow(X_Dpy, mc->win);
XMoveResizeWindow(X_Dpy, mc->win, mc->geom.x, mc->geom.y,
mc->geom.w, mc->geom.h);
n = 1;
XftDrawStringUtf8(sc->menu.xftdraw,
XftDrawStringUtf8(mc->xftdraw,
&sc->xftcolor[CWM_COLOR_MENU_FONT], sc->xftfont,
0, sc->xftfont->ascent,
(const FcChar8*)mc->dispstr, strlen(mc->dispstr));
@ -395,7 +408,7 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
if (mc->geom.y + y > area.h)
break;
XftDrawStringUtf8(sc->menu.xftdraw,
XftDrawStringUtf8(mc->xftdraw,
&sc->xftcolor[CWM_COLOR_MENU_FONT], sc->xftfont,
0, y,
(const FcChar8*)mi->print, strlen(mi->print));
@ -420,11 +433,11 @@ menu_draw_entry(struct menu_ctx *mc, struct menu_q *resultq,
return;
color = (active) ? CWM_COLOR_MENU_FG : CWM_COLOR_MENU_BG;
XftDrawRect(sc->menu.xftdraw, &sc->xftcolor[color], 0,
XftDrawRect(mc->xftdraw, &sc->xftcolor[color], 0,
(sc->xftfont->height + 1) * entry, mc->geom.w,
(sc->xftfont->height + 1) + sc->xftfont->descent);
color = (active) ? CWM_COLOR_MENU_FONT_SEL : CWM_COLOR_MENU_FONT;
XftDrawStringUtf8(sc->menu.xftdraw,
XftDrawStringUtf8(mc->xftdraw,
&sc->xftcolor[color], sc->xftfont,
0, (sc->xftfont->height + 1) * entry + sc->xftfont->ascent + 1,
(const FcChar8*)mi->print, strlen(mi->print));
@ -604,34 +617,3 @@ menuq_clear(struct menu_q *mq)
free(mi);
}
}
void
menu_windraw(struct screen_ctx *sc, Window win, const char *fmt, ...)
{
va_list ap;
int i;
char *text;
XGlyphInfo extents;
va_start(ap, fmt);
i = vasprintf(&text, fmt, ap);
va_end(ap);
if (i < 0 || text == NULL)
err(1, "vasprintf");
XftTextExtentsUtf8(X_Dpy, sc->xftfont, (const FcChar8*)text,
strlen(text), &extents);
XReparentWindow(X_Dpy, sc->menu.win, win, 0, 0);
XMoveResizeWindow(X_Dpy, sc->menu.win, 0, 0,
extents.xOff, sc->xftfont->height);
XMapWindow(X_Dpy, sc->menu.win);
XClearWindow(X_Dpy, sc->menu.win);
XftDrawStringUtf8(sc->menu.xftdraw, &sc->xftcolor[CWM_COLOR_MENU_FONT],
sc->xftfont, 0, sc->xftfont->ascent + 1,
(const FcChar8*)text, strlen(text));
free(text);
}

View File

@ -24,6 +24,7 @@
#include <err.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -40,7 +41,6 @@ screen_init(int which)
Window *wins, w0, w1, active = None;
XSetWindowAttributes rootattr;
unsigned int nwins, w;
int i;
sc = xmalloc(sizeof(*sc));
@ -60,14 +60,11 @@ screen_init(int which)
xu_ewmh_net_supported(sc);
xu_ewmh_net_supported_wm_check(sc);
conf_group(sc);
screen_update_geometry(sc);
for (i = 0; i < Conf.ngroups; i++)
group_init(sc, i);
xu_ewmh_net_desktop_names(sc);
xu_ewmh_net_wm_desktop_viewport(sc);
xu_ewmh_net_wm_number_of_desktops(sc);
xu_ewmh_net_number_of_desktops(sc);
xu_ewmh_net_showing_desktop(sc);
xu_ewmh_net_virtual_roots(sc);
active = xu_ewmh_get_net_active_window(sc);
@ -106,7 +103,7 @@ screen_find(Window win)
if (sc->rootwin == win)
return(sc);
}
warnx("%s: failure win 0x%lu\n", __func__, win);
warnx("%s: failure win 0x%lx", __func__, win);
return(NULL);
}
@ -217,6 +214,7 @@ screen_update_geometry(struct screen_ctx *sc)
}
xu_ewmh_net_desktop_geometry(sc);
xu_ewmh_net_desktop_viewport(sc);
xu_ewmh_net_workarea(sc);
}
@ -253,3 +251,47 @@ screen_assert_clients_within(struct screen_ctx *sc)
}
}
}
void
screen_prop_win_create(struct screen_ctx *sc, Window win)
{
sc->prop.win = XCreateSimpleWindow(X_Dpy, win, 0, 0, 1, 1, 0,
sc->xftcolor[CWM_COLOR_MENU_BG].pixel,
sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
sc->prop.xftdraw = XftDrawCreate(X_Dpy, sc->prop.win,
sc->visual, sc->colormap);
XMapWindow(X_Dpy, sc->prop.win);
}
void
screen_prop_win_destroy(struct screen_ctx *sc)
{
XftDrawDestroy(sc->prop.xftdraw);
XDestroyWindow(X_Dpy, sc->prop.win);
}
void
screen_prop_win_draw(struct screen_ctx *sc, const char *fmt, ...)
{
va_list ap;
int i;
char *text;
XGlyphInfo extents;
va_start(ap, fmt);
i = vasprintf(&text, fmt, ap);
va_end(ap);
if (i < 0 || text == NULL)
err(1, "vasprintf");
XftTextExtentsUtf8(X_Dpy, sc->xftfont, (const FcChar8*)text,
strlen(text), &extents);
XResizeWindow(X_Dpy, sc->prop.win, extents.xOff, sc->xftfont->height);
XClearWindow(X_Dpy, sc->prop.win);
XftDrawStringUtf8(sc->prop.xftdraw, &sc->xftcolor[CWM_COLOR_MENU_FONT],
sc->xftfont, 0, sc->xftfont->ascent + 1,
(const FcChar8*)text, strlen(text));
free(text);
}

View File

@ -75,11 +75,15 @@ static void
xev_handle_maprequest(XEvent *ee)
{
XMapRequestEvent *e = &ee->xmaprequest;
struct client_ctx *cc = NULL, *old_cc;
struct screen_ctx *sc;
struct client_ctx *cc, *old_cc;
LOG_DEBUG3("window: 0x%lx", e->window);
LOG_DEBUG3("parent: 0x%lx window: 0x%lx", e->parent, e->window);
if ((old_cc = client_current()) != NULL)
if ((sc = screen_find(e->parent)) == NULL)
return;
if ((old_cc = client_current(sc)) != NULL)
client_ptrsave(old_cc);
if ((cc = client_find(e->window)) == NULL)
@ -207,11 +211,9 @@ xev_handle_propertynotify(XEvent *ee)
break;
}
} else {
TAILQ_FOREACH(sc, &Screenq, entry) {
if (sc->rootwin == e->window) {
if (e->atom == ewmh[_NET_DESKTOP_NAMES])
xu_ewmh_net_desktop_names(sc);
}
if (e->atom == ewmh[_NET_DESKTOP_NAMES]) {
if ((sc = screen_find(e->window)) != NULL)
xu_ewmh_net_desktop_names(sc);
}
}
}
@ -238,7 +240,11 @@ xev_handle_buttonpress(XEvent *ee)
struct screen_ctx *sc;
struct bind_ctx *mb;
LOG_DEBUG3("window: 0x%lx", e->window);
LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx",
e->root, e->window, e->subwindow);
if ((sc = screen_find(e->root)) == NULL)
return;
e->state &= ~IGNOREMODMASK;
@ -246,22 +252,17 @@ xev_handle_buttonpress(XEvent *ee)
if (e->button == mb->press.button && e->state == mb->modmask)
break;
}
if (mb == NULL)
return;
mb->cargs->xev = CWM_XEV_BTN;
switch (mb->context) {
case CWM_CONTEXT_CC:
if (((cc = client_find(e->window)) == NULL) &&
(cc = client_current()) == NULL)
((cc = client_current(sc)) == NULL))
return;
(*mb->callback)(cc, mb->cargs);
break;
case CWM_CONTEXT_SC:
if (e->window != e->root)
return;
if ((sc = screen_find(e->window)) == NULL)
return;
(*mb->callback)(sc, mb->cargs);
break;
case CWM_CONTEXT_NONE:
@ -276,7 +277,8 @@ xev_handle_buttonrelease(XEvent *ee)
XButtonEvent *e = &ee->xbutton;
struct client_ctx *cc;
LOG_DEBUG3("window: 0x%lx", ee->xbutton.window);
LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx",
e->root, e->window, e->subwindow);
if ((cc = client_find(e->window)) != NULL) {
if (cc->flags & (CLIENT_ACTIVE | CLIENT_HIGHLIGHT)) {
@ -296,7 +298,11 @@ xev_handle_keypress(XEvent *ee)
KeySym keysym, skeysym;
unsigned int modshift;
LOG_DEBUG3("window: 0x%lx", e->window);
LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx",
e->root, e->window, e->subwindow);
if ((sc = screen_find(e->root)) == NULL)
return;
keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0);
skeysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 1);
@ -315,20 +321,17 @@ xev_handle_keypress(XEvent *ee)
if (kb->press.keysym == ((modshift == 0) ? keysym : skeysym))
break;
}
if (kb == NULL)
return;
kb->cargs->xev = CWM_XEV_KEY;
switch (kb->context) {
case CWM_CONTEXT_CC:
if (((cc = client_find(e->window)) == NULL) &&
(cc = client_current()) == NULL)
if (((cc = client_find(e->subwindow)) == NULL) &&
((cc = client_current(sc)) == NULL))
return;
(*kb->callback)(cc, kb->cargs);
break;
case CWM_CONTEXT_SC:
if ((sc = screen_find(e->window)) == NULL)
return;
(*kb->callback)(sc, kb->cargs);
break;
case CWM_CONTEXT_NONE:
@ -349,7 +352,8 @@ xev_handle_keyrelease(XEvent *ee)
KeySym keysym;
unsigned int i;
LOG_DEBUG3("window: 0x%lx", e->window);
LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx",
e->root, e->window, e->subwindow);
if ((sc = screen_find(e->root)) == NULL)
return;
@ -357,7 +361,7 @@ xev_handle_keyrelease(XEvent *ee)
keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0);
for (i = 0; i < nitems(modkeys); i++) {
if (keysym == modkeys[i]) {
if ((cc = client_current()) != NULL) {
if ((cc = client_current(sc)) != NULL) {
if (sc->cycling) {
sc->cycling = 0;
client_mtf(cc);
@ -393,7 +397,7 @@ xev_handle_clientmessage(XEvent *ee)
}
} else if (e->message_type == ewmh[_NET_ACTIVE_WINDOW]) {
if ((cc = client_find(e->window)) != NULL) {
if ((old_cc = client_current()) != NULL)
if ((old_cc = client_current(NULL)) != NULL)
client_ptrsave(old_cc);
client_show(cc);
client_ptrwarp(cc);
@ -408,7 +412,9 @@ xev_handle_clientmessage(XEvent *ee)
if (e->data.l[0] == (unsigned long)-1)
group_movetogroup(cc, 0);
else
group_movetogroup(cc, e->data.l[0]);
if (e->data.l[0] >= 0 &&
e->data.l[0] < Conf.ngroups)
group_movetogroup(cc, e->data.l[0]);
}
} else if (e->message_type == ewmh[_NET_WM_STATE]) {
if ((cc = client_find(e->window)) != NULL) {
@ -417,7 +423,9 @@ xev_handle_clientmessage(XEvent *ee)
}
} else if (e->message_type == ewmh[_NET_CURRENT_DESKTOP]) {
if ((sc = screen_find(e->window)) != NULL) {
group_only(sc, e->data.l[0]);
if (e->data.l[0] >= 0 &&
e->data.l[0] < Conf.ngroups)
group_only(sc, e->data.l[0]);
}
}
}
@ -425,20 +433,17 @@ xev_handle_clientmessage(XEvent *ee)
static void
xev_handle_randr(XEvent *ee)
{
XRRScreenChangeNotifyEvent *rev = (XRRScreenChangeNotifyEvent *)ee;
XRRScreenChangeNotifyEvent *e = (XRRScreenChangeNotifyEvent *)ee;
struct screen_ctx *sc;
int i;
LOG_DEBUG3("new size: %d/%d", rev->width, rev->height);
LOG_DEBUG3("size: %d/%d", e->width, e->height);
i = XRRRootToScreen(X_Dpy, rev->root);
TAILQ_FOREACH(sc, &Screenq, entry) {
if (sc->which == i) {
XRRUpdateConfiguration(ee);
screen_update_geometry(sc);
screen_assert_clients_within(sc);
}
}
if ((sc = screen_find(e->root)) == NULL)
return;
XRRUpdateConfiguration(ee);
screen_update_geometry(sc);
screen_assert_clients_within(sc);
}
/*
@ -479,9 +484,9 @@ xev_process(void)
while (XPending(X_Dpy)) {
XNextEvent(X_Dpy, &e);
if (e.type - Conf.xrandr_event_base == RRScreenChangeNotify)
if ((e.type - Conf.xrandr_event_base) == RRScreenChangeNotify)
xev_handle_randr(&e);
else if (e.type < LASTEvent && xev_handlers[e.type] != NULL)
else if ((e.type < LASTEvent) && (xev_handlers[e.type] != NULL))
(*xev_handlers[e.type])(&e);
}
}

22
xutil.c
View File

@ -128,6 +128,16 @@ xu_ewmh_net_desktop_geometry(struct screen_ctx *sc)
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)geom , 2);
}
void
xu_ewmh_net_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],
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2);
}
void
xu_ewmh_net_workarea(struct screen_ctx *sc)
{
@ -212,17 +222,7 @@ xu_ewmh_get_net_active_window(struct screen_ctx *sc)
}
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],
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2);
}
void
xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *sc)
xu_ewmh_net_number_of_desktops(struct screen_ctx *sc)
{
long ndesks = Conf.ngroups;