summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--calmwm.c9
-rw-r--r--calmwm.h82
-rw-r--r--client.c4
-rw-r--r--group.c104
-rw-r--r--kbfunc.c68
-rw-r--r--menu.c6
-rw-r--r--mousefunc.c15
-rw-r--r--screen.c13
-rw-r--r--xevents.c26
9 files changed, 163 insertions, 164 deletions
diff --git a/calmwm.c b/calmwm.c
index 8cc62d5..4bd1567 100644
--- a/calmwm.c
+++ b/calmwm.c
@@ -30,8 +30,6 @@ Cursor				 Cursor_default;
 Cursor				 Cursor_question;
 
 struct screen_ctx_q		 Screenq = TAILQ_HEAD_INITIALIZER(Screenq);
-struct screen_ctx		*Curscreen;
-
 struct client_ctx_q		 Clientq = TAILQ_HEAD_INITIALIZER(Clientq);
 
 int				 HasXinerama, HasRandr, Randr_ev;
@@ -73,8 +71,6 @@ main(int argc, char **argv)
 	Starting = 1;
 	dpy_init(display_name);
 
-	group_init();
-
 	bzero(&Conf, sizeof(Conf));
 	conf_setup(&Conf, conf_file);
 	xu_getatoms();
@@ -149,8 +145,6 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
 	int			 fake;
 	u_int			 ndesks = CALMWM_NGROUPS, nwins, i;
 
-	Curscreen = sc;
-
 	sc->which = which;
 	sc->rootwin = RootWindow(X_Dpy, sc->which);
 	sc->xmax = DisplayWidth(X_Dpy, sc->which);
@@ -158,6 +152,7 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
 
 	conf_color(&Conf, sc);
 
+	group_init(sc);
 	font_init(sc);
 	conf_font(&Conf, sc);
 
@@ -187,7 +182,7 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
 	}
 	XFree(wins);
 
-	screen_updatestackingorder();
+	screen_updatestackingorder(sc);
 
 	rootattr.event_mask = ChildMask|PropertyChangeMask|EnterWindowMask|
 	    LeaveWindowMask|ColormapChangeMask|ButtonMask;
diff --git a/calmwm.h b/calmwm.h
index 0dc1ffe..9ca583f 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -59,31 +59,48 @@ struct color {
 struct client_ctx;
 
 TAILQ_HEAD(cycle_entry_q, client_ctx);
+TAILQ_HEAD(group_ctx_q, group_ctx);
+TAILQ_HEAD(client_ctx_q, client_ctx);
+
+#define CALMWM_NGROUPS 9
+struct group_ctx {
+	TAILQ_ENTRY(group_ctx)	 entry;
+	struct client_ctx_q	 clients;
+	const char		*name;
+	int			 shortcut;
+	int			 hidden;
+	int			 nhidden;
+	int			 highstack;
+};
 
 struct screen_ctx {
-	TAILQ_ENTRY(screen_ctx)	entry;
+	TAILQ_ENTRY(screen_ctx)	 entry;
 
-	u_int		 which;
-	Window		 rootwin;
-	Window		 menuwin;
+	u_int			 which;
+	Window			 rootwin;
+	Window			 menuwin;
 
-	struct color	 color[CWM_COLOR_MAX];
-	GC		 gc;
+	struct color		 color[CWM_COLOR_MAX];
+	GC			 gc;
 
-	int		 altpersist;
+	int			 altpersist;
 
-	int		 xmax;
-	int		 ymax;
+	int			 xmax;
+	int			 ymax;
 
-	struct cycle_entry_q mruq;
+	struct cycle_entry_q	 mruq;
 
-	XftDraw		*xftdraw;
-	XftColor	 xftcolor;
-	XftFont		*font;
-	u_int		 fontheight;
+	XftDraw			*xftdraw;
+	XftColor		 xftcolor;
+	XftFont			*font;
+	u_int			 fontheight;
 
-	int		 xinerama_no;
-	XineramaScreenInfo *xinerama;
+	int			 xinerama_no;
+	XineramaScreenInfo	*xinerama;
+	struct group_ctx	*group_active;
+	struct group_ctx	 groups[CALMWM_NGROUPS];
+	int			 group_hideall;
+	struct group_ctx_q	 groupq;
 };
 
 TAILQ_HEAD(screen_ctx_q, screen_ctx);
@@ -157,23 +174,8 @@ struct client_ctx {
 	char			*app_cliarg;
 };
 
-TAILQ_HEAD(client_ctx_q, client_ctx);
-
 extern const char *shortcut_to_name[];
 
-#define CALMWM_NGROUPS 9
-struct group_ctx {
-	TAILQ_ENTRY(group_ctx)	 entry;
-	struct client_ctx_q	 clients;
-	const char		*name;
-	int			 shortcut;
-	int			 hidden;
-	int			 nhidden;
-	int			 highstack;
-};
-
-TAILQ_HEAD(group_ctx_q, group_ctx);
-
 /* Autogroups */
 struct autogroupwin {
 	TAILQ_ENTRY(autogroupwin) entry;
@@ -354,11 +356,12 @@ void			 client_vertmaximize(struct client_ctx *);
 void			 client_horizmaximize(struct client_ctx *);
 void			 client_map(struct client_ctx *);
 void			 client_mtf(struct client_ctx *);
-struct client_ctx	*client_cycle(int);
+struct client_ctx	*client_cycle(struct screen_ctx *, int);
 void			 client_getsizehints(struct client_ctx *);
 void			 client_applysizehints(struct client_ctx *);
 
-struct menu  		*menu_filter(struct menu_q *, char *, char *, int,
+struct menu  		*menu_filter(struct screen_ctx *, struct menu_q *,
+			     char *, char *, int,
 			     void (*)(struct menu_q *, struct menu_q *, char *),
 			     void (*)(struct menu *, int));
 void			 menu_init(struct screen_ctx *);
@@ -397,8 +400,7 @@ void			*xcalloc(size_t, size_t);
 char			*xstrdup(const char *);
 
 struct screen_ctx	*screen_fromroot(Window);
-struct screen_ctx	*screen_current(void);
-void			 screen_updatestackingorder(void);
+void			 screen_updatestackingorder(struct screen_ctx *);
 void			 screen_init_xinerama(struct screen_ctx *);
 XineramaScreenInfo	*screen_find_xinerama(struct screen_ctx *, int, int);
 
@@ -471,14 +473,14 @@ void			 search_match_text(struct menu_q *, struct menu_q *,
 void			 search_match_exec(struct menu_q *, struct menu_q *,
 			     char *);
 
-void			 group_init(void);
-void			 group_hidetoggle(int);
-void			 group_only(int);
-void			 group_cycle(int);
+void			 group_init(struct screen_ctx *);
+void			 group_hidetoggle(struct screen_ctx *, int);
+void			 group_only(struct screen_ctx *, int);
+void			 group_cycle(struct screen_ctx *, int);
 void			 group_sticky(struct client_ctx *);
 void			 group_client_delete(struct client_ctx *);
 void			 group_menu(XButtonEvent *);
-void			 group_alltoggle(void);
+void			 group_alltoggle(struct screen_ctx *);
 void			 group_sticky_toggle_enter(struct client_ctx *);
 void			 group_sticky_toggle_exit(struct client_ctx *);
 void			 group_autogroup(struct client_ctx *);
diff --git a/client.c b/client.c
index 1d4118b..2701f80 100644
--- a/client.c
+++ b/client.c
@@ -548,14 +548,12 @@ match:
 }
 
 struct client_ctx *
-client_cycle(int reverse)
+client_cycle(struct screen_ctx *sc, int reverse)
 {
 	struct client_ctx	*oldcc, *newcc;
-	struct screen_ctx	*sc;
 	int			 again = 1;
 
 	oldcc = client_current();
-	sc = screen_current();
 
 	/* If no windows then you cant cycle */
 	if (TAILQ_EMPTY(&sc->mruq))
diff --git a/group.c b/group.c
index 86aedc2..6b20027 100644
--- a/group.c
+++ b/group.c
@@ -24,15 +24,10 @@
 
 static void		 group_add(struct group_ctx *, struct client_ctx *);
 static void		 group_remove(struct client_ctx *);
-static void		 group_hide(struct group_ctx *);
-static void		 group_show(struct group_ctx *);
+static void		 group_hide(struct screen_ctx *, struct group_ctx *);
+static void		 group_show(struct screen_ctx *, struct group_ctx *);
 static void		 group_fix_hidden_state(struct group_ctx *);
 
-struct group_ctx	*Group_active = NULL;
-struct group_ctx	 Groups[CALMWM_NGROUPS];
-int			 Grouphideall = 0;
-struct group_ctx_q	 Groupq;
-
 const char *shortcut_to_name[] = {
 	"nogroup", "one", "two", "three", "four", "five", "six",
 	"seven", "eight", "nine"
@@ -72,11 +67,11 @@ group_remove(struct client_ctx *cc)
 }
 
 static void
-group_hide(struct group_ctx *gc)
+group_hide(struct screen_ctx *sc, struct group_ctx *gc)
 {
 	struct client_ctx	*cc;
 
-	screen_updatestackingorder();
+	screen_updatestackingorder(sc);
 
 	gc->nhidden = 0;
 	gc->highstack = 0;
@@ -90,7 +85,7 @@ group_hide(struct group_ctx *gc)
 }
 
 static void
-group_show(struct group_ctx *gc)
+group_show(struct screen_ctx *sc, struct group_ctx *gc)
 {
 	struct client_ctx	*cc;
 	Window			*winlist;
@@ -123,36 +118,40 @@ group_show(struct group_ctx *gc)
 	xfree(winlist);
 
 	gc->hidden = 0;
-	Group_active = gc;
+	sc->group_active = gc;
 }
 
 void
-group_init(void)
+group_init(struct screen_ctx *sc)
 {
 	int	 i;
 
-	TAILQ_INIT(&Groupq);
+	TAILQ_INIT(&sc->groupq);
+	sc->group_hideall = 0;
+	sc->group_active = NULL;
 
 	for (i = 0; i < CALMWM_NGROUPS; i++) {
-		TAILQ_INIT(&Groups[i].clients);
-		Groups[i].hidden = 0;
-		Groups[i].shortcut = i + 1;
-		Groups[i].name = shortcut_to_name[Groups[i].shortcut];
-		TAILQ_INSERT_TAIL(&Groupq, &Groups[i], entry);
+		TAILQ_INIT(&sc->groups[i].clients);
+		sc->groups[i].hidden = 0;
+		sc->groups[i].shortcut = i + 1;
+		sc->groups[i].name = shortcut_to_name[sc->groups[i].shortcut];
+		TAILQ_INSERT_TAIL(&sc->groupq, &sc->groups[i], entry);
 	}
 
-	Group_active = &Groups[0];
+	sc->group_active = &sc->groups[0];
 }
 
 void
 group_movetogroup(struct client_ctx *cc, int idx)
 {
+	struct screen_ctx	*sc = cc->sc;
+
 	if (idx < 0 || idx >= CALMWM_NGROUPS)
 		err(1, "group_movetogroup: index out of range (%d)", idx);
 
-	if(Group_active != &Groups[idx])
+	if(sc->group_active != &sc->groups[idx])
 		client_hide(cc);
-	group_add(&Groups[idx], cc);
+	group_add(&sc->groups[idx], cc);
 }
 
 /*
@@ -161,9 +160,10 @@ group_movetogroup(struct client_ctx *cc, int idx)
 void
 group_sticky_toggle_enter(struct client_ctx *cc)
 {
+	struct screen_ctx	*sc = cc->sc;
 	struct group_ctx	*gc;
 
-	gc = Group_active;
+	gc = sc->group_active;
 
 	if (gc == cc->group) {
 		group_remove(cc);
@@ -202,28 +202,29 @@ group_fix_hidden_state(struct group_ctx *gc)
 }
 
 void
-group_hidetoggle(int idx)
+group_hidetoggle(struct screen_ctx *sc, int idx)
 {
 	struct group_ctx	*gc;
 
 	if (idx < 0 || idx >= CALMWM_NGROUPS)
 		err(1, "group_hidetoggle: index out of range (%d)", idx);
 
-	gc = &Groups[idx];
+	gc = &sc->groups[idx];
 
 	group_fix_hidden_state(gc);
 
 	if (gc->hidden)
-		group_show(gc);
+		group_show(sc, gc);
 	else {
-		group_hide(gc);
+		group_hide(sc, gc);
+		/* XXX wtf? */
 		if (TAILQ_EMPTY(&gc->clients))
-			Group_active = gc;
+			sc->group_active = gc;
 	}
 }
 
 void
-group_only(int idx)
+group_only(struct screen_ctx *sc, int idx)
 {
 	int	 i;
 
@@ -232,9 +233,9 @@ group_only(int idx)
 
 	for (i = 0; i < CALMWM_NGROUPS; i++) {
 		if (i == idx)
-			group_show(&Groups[i]);
+			group_show(sc, &sc->groups[i]);
 		else
-			group_hide(&Groups[i]);
+			group_hide(sc, &sc->groups[i]);
 	}
 }
 
@@ -242,37 +243,37 @@ group_only(int idx)
  * Cycle through active groups.  If none exist, then just stay put.
  */
 void
-group_cycle(int reverse)
+group_cycle(struct screen_ctx *sc, int reverse)
 {
 	struct group_ctx	*gc, *showgroup = NULL;
 
-	assert(Group_active != NULL);
+	assert(sc->group_active != NULL);
 
-	gc = Group_active;
+	gc = sc->group_active;
 	for (;;) {
 		gc = reverse ? TAILQ_PREV(gc, group_ctx_q, entry) :
 		    TAILQ_NEXT(gc, entry);
 		if (gc == NULL)
-			gc = reverse ? TAILQ_LAST(&Groupq, group_ctx_q) :
-			    TAILQ_FIRST(&Groupq);
-		if (gc == Group_active)
+			gc = reverse ? TAILQ_LAST(&sc->groupq, group_ctx_q) :
+			    TAILQ_FIRST(&sc->groupq);
+		if (gc == sc->group_active)
 			break;
 
 		if (!TAILQ_EMPTY(&gc->clients) && showgroup == NULL)
 			showgroup = gc;
 		else if (!gc->hidden)
-			group_hide(gc);
+			group_hide(sc, gc);
 	}
 
 	if (showgroup == NULL)
 		return;
 
-	group_hide(Group_active);
+	group_hide(sc, sc->group_active);
 
 	if (showgroup->hidden)
-		group_show(showgroup);
+		group_show(sc, showgroup);
 	else
-		Group_active = showgroup;
+		sc->group_active = showgroup;
 }
 
 /* called when a client is deleted */
@@ -289,15 +290,17 @@ group_client_delete(struct client_ctx *cc)
 void
 group_menu(XButtonEvent *e)
 {
+	struct screen_ctx	*sc;
 	struct group_ctx	*gc;
 	struct menu		*mi;
 	struct menu_q		 menuq;
 	int			 i;
 
+	sc = screen_fromroot(e->root);
 	TAILQ_INIT(&menuq);
 
 	for (i = 0; i < CALMWM_NGROUPS; i++) {
-		gc = &Groups[i];
+		gc = &sc->groups[i];
 
 		if (TAILQ_EMPTY(&gc->clients))
 			continue;
@@ -316,14 +319,14 @@ group_menu(XButtonEvent *e)
 	if (TAILQ_EMPTY(&menuq))
 		return;
 
-	mi = menu_filter(&menuq, NULL, NULL, 0, NULL, NULL);
+	mi = menu_filter(sc, &menuq, NULL, NULL, 0, NULL, NULL);
 
 	if (mi == NULL || mi->ctx == NULL)
 		goto cleanup;
 
 	gc = (struct group_ctx *)mi->ctx;
 
-	(gc->hidden) ? group_show(gc) : group_hide(gc);
+	(gc->hidden) ? group_show(sc, gc) : group_hide(sc, gc);
 
 cleanup:
 	while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
@@ -333,23 +336,24 @@ cleanup:
 }
 
 void
-group_alltoggle(void)
+group_alltoggle(struct screen_ctx *sc)
 {
 	int	 i;
 
 	for (i = 0; i < CALMWM_NGROUPS; i++) {
-		if (Grouphideall)
-			group_show(&Groups[i]);
+		if (sc->group_hideall)
+			group_show(sc, &sc->groups[i]);
 		else
-			group_hide(&Groups[i]);
+			group_hide(sc, &sc->groups[i]);
 	}
 
-	Grouphideall = (Grouphideall) ? 0 : 1;
+	sc->group_hideall = (!sc->group_hideall);
 }
 
 void
 group_autogroup(struct client_ctx *cc)
 {
+	struct screen_ctx	*sc = cc->sc;
 	struct autogroupwin	*aw;
 	struct group_ctx	*gc;
 	unsigned char		*grpstr = NULL;
@@ -375,7 +379,7 @@ group_autogroup(struct client_ctx *cc)
 	if (strncmp("nogroup", group, 7) == 0)
 		return;
 
-	TAILQ_FOREACH(gc, &Groupq, entry) {
+	TAILQ_FOREACH(gc, &sc->groupq, entry) {
 		if (strcmp(shortcut_to_name[gc->shortcut], group) == 0) {
 			group_add(gc, cc);
 			return;
@@ -383,6 +387,6 @@ group_autogroup(struct client_ctx *cc)
 	}
 
 	if (Conf.flags & CONF_STICKY_GROUPS)
-		group_add(Group_active, cc);
+		group_add(sc->group_active, cc);
 
 }
diff --git a/kbfunc.c b/kbfunc.c
index c6c9ac1..c9377cd 100644
--- a/kbfunc.c
+++ b/kbfunc.c
@@ -126,10 +126,12 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
 void
 kbfunc_client_search(struct client_ctx *cc, union arg *arg)
 {
+	struct screen_ctx	*sc;
 	struct client_ctx	*old_cc;
 	struct menu		*mi;
 	struct menu_q		 menuq;
 
+	sc = cc->sc;
 	old_cc = client_current();
 
 	TAILQ_INIT(&menuq);
@@ -141,7 +143,7 @@ kbfunc_client_search(struct client_ctx *cc, union arg *arg)
 		TAILQ_INSERT_TAIL(&menuq, mi, entry);
 	}
 
-	if ((mi = menu_filter(&menuq, "window", NULL, 0,
+	if ((mi = menu_filter(sc, &menuq, "window", NULL, 0,
 	    search_match_client, search_print_client)) != NULL) {
 		cc = (struct client_ctx *)mi->ctx;
 		if (cc->flags & CLIENT_HIDDEN)
@@ -161,10 +163,12 @@ kbfunc_client_search(struct client_ctx *cc, union arg *arg)
 void
 kbfunc_menu_search(struct client_ctx *cc, union arg *arg)
 {
-	struct cmd	*cmd;
-	struct menu	*mi;
-	struct menu_q	 menuq;
+	struct screen_ctx	*sc;
+	struct cmd		*cmd;
+	struct menu		*mi;
+	struct menu_q		 menuq;
 
+	sc = cc->sc;
 	TAILQ_INIT(&menuq);
 
 	TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
@@ -174,7 +178,7 @@ kbfunc_menu_search(struct client_ctx *cc, union arg *arg)
 		TAILQ_INSERT_TAIL(&menuq, mi, entry);
 	}
 
-	if ((mi = menu_filter(&menuq, "application", NULL, 0,
+	if ((mi = menu_filter(sc, &menuq, "application", NULL, 0,
 	    search_match_text, NULL)) != NULL)
 		u_spawn(((struct cmd *)mi->ctx)->image);
 
@@ -189,13 +193,13 @@ kbfunc_client_cycle(struct client_ctx *cc, union arg *arg)
 {
 	struct screen_ctx	*sc;
 
-	sc = screen_current();
+	sc = cc->sc;
 
 	/* XXX for X apps that ignore events */
 	XGrabKeyboard(X_Dpy, sc->rootwin, True,
 	    GrabModeAsync, GrabModeAsync, CurrentTime);
 
-	client_cycle(arg->i);
+	client_cycle(sc, arg->i);
 }
 
 void
@@ -226,15 +230,16 @@ void
 kbfunc_exec(struct client_ctx *cc, union arg *arg)
 {
 #define NPATHS 256
-	char		**ap, *paths[NPATHS], *path, *pathcpy, *label;
-	char		 tpath[MAXPATHLEN];
-	int		 l, i;
-	DIR		*dirp;
-	struct dirent	*dp;
-	struct menu	*mi;
-	struct menu_q	 menuq;
+	struct screen_ctx	*sc;
+	char			**ap, *paths[NPATHS], *path, *pathcpy, *label;
+	char			 tpath[MAXPATHLEN];
+	DIR			*dirp;
+	struct dirent		*dp;
+	struct menu		*mi;
+	struct menu_q		 menuq;
+	int			 l, i, cmd = arg->i;
 
-	int cmd = arg->i;
+	sc = cc->sc;
 	switch (cmd) {
 		case CWM_EXEC_PROGRAM:
 			label = "exec";
@@ -283,7 +288,7 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg)
 	}
 	xfree(path);
 
-	if ((mi = menu_filter(&menuq, label, NULL, 1,
+	if ((mi = menu_filter(sc, &menuq, label, NULL, 1,
 	    search_match_exec, NULL)) != NULL) {
 		if (mi->text[0] == '\0')
 			goto out;
@@ -312,14 +317,17 @@ out:
 void
 kbfunc_ssh(struct client_ctx *cc, union arg *arg)
 {
-	struct menu	*mi;
-	struct menu_q	 menuq;
-	FILE		*fp;
-	char		*buf, *lbuf, *p, *home;
-	char		 hostbuf[MAXHOSTNAMELEN], filename[MAXPATHLEN];
-	char		 cmd[256];
-	int		 l;
-	size_t		 len;
+	struct screen_ctx	*sc;
+	struct menu		*mi;
+	struct menu_q		 menuq;
+	FILE			*fp;
+	char			*buf, *lbuf, *p, *home;
+	char			 hostbuf[MAXHOSTNAMELEN], filename[MAXPATHLEN];
+	char			 cmd[256];
+	int			 l;
+	size_t			 len;
+
+	sc = cc->sc;
 
 	if ((home = getenv("HOME")) == NULL)
 		return;
@@ -360,7 +368,7 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg)
 	xfree(lbuf);
 	fclose(fp);
 
-	if ((mi = menu_filter(&menuq, "ssh", NULL, 1,
+	if ((mi = menu_filter(sc, &menuq, "ssh", NULL, 1,
 	    search_match_exec, NULL)) != NULL) {
 		if (mi->text[0] == '\0')
 			goto out;
@@ -389,7 +397,7 @@ kbfunc_client_label(struct client_ctx *cc, union arg *arg)
 
 	current = cc->label;
 
-	if ((mi = menu_filter(&menuq, "label", current, 1,
+	if ((mi = menu_filter(cc->sc, &menuq, "label", current, 1,
 	    search_match_text, NULL)) != NULL) {
 		if (cc->label != NULL)
 			xfree(cc->label);
@@ -407,25 +415,25 @@ kbfunc_client_delete(struct client_ctx *cc, union arg *arg)
 void
 kbfunc_client_group(struct client_ctx *cc, union arg *arg)
 {
-	group_hidetoggle(KBTOGROUP(arg->i));
+	group_hidetoggle(cc->sc, KBTOGROUP(arg->i));
 }
 
 void
 kbfunc_client_grouponly(struct client_ctx *cc, union arg *arg)
 {
-	group_only(KBTOGROUP(arg->i));
+	group_only(cc->sc, KBTOGROUP(arg->i));
 }
 
 void
 kbfunc_client_cyclegroup(struct client_ctx *cc, union arg *arg)
 {
-	group_cycle(arg->i);
+	group_cycle(cc->sc, arg->i);
 }
 
 void
 kbfunc_client_nogroup(struct client_ctx *cc, union arg *arg)
 {
-	group_alltoggle();
+	group_alltoggle(cc->sc);
 }
 
 void
diff --git a/menu.c b/menu.c
index 2ac0d13..69f0588 100644
--- a/menu.c
+++ b/menu.c
@@ -69,11 +69,11 @@ menu_init(struct screen_ctx *sc)
 }
 
 struct menu *
-menu_filter(struct menu_q *menuq, char *prompt, char *initial, int dummy,
+menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
+    char *initial, int dummy,
     void (*match)(struct menu_q *, struct menu_q *, char *),
     void (*print)(struct menu *, int))
 {
-	struct screen_ctx	*sc;
 	struct menu_ctx		 mc;
 	struct menu_q		 resultq;
 	struct menu		*mi = NULL;
@@ -81,8 +81,6 @@ menu_filter(struct menu_q *menuq, char *prompt, char *initial, int dummy,
 	Window			 focuswin;
 	int			 evmask, focusrevert;
 
-	sc = screen_current();
-
 	TAILQ_INIT(&resultq);
 
 	bzero(&mc, sizeof(mc));
diff --git a/mousefunc.c b/mousefunc.c
index c0b3b1a..b66f64c 100644
--- a/mousefunc.c
+++ b/mousefunc.c
@@ -198,11 +198,13 @@ mousefunc_menu_group(struct client_ctx *cc, void *arg)
 void
 mousefunc_menu_unhide(struct client_ctx *cc, void *arg)
 {
+	struct screen_ctx	*sc;
 	struct client_ctx	*old_cc;
 	struct menu		*mi;
 	struct menu_q		 menuq;
 	char			*wname;
 
+	sc = cc->sc;
 	old_cc = client_current();
 
 	TAILQ_INIT(&menuq);
@@ -221,7 +223,7 @@ mousefunc_menu_unhide(struct client_ctx *cc, void *arg)
 	if (TAILQ_EMPTY(&menuq))
 		return;
 
-	mi = menu_filter(&menuq, NULL, NULL, 0, NULL, NULL);
+	mi = menu_filter(sc, &menuq, NULL, NULL, 0, NULL, NULL);
 	if (mi != NULL) {
 		cc = (struct client_ctx *)mi->ctx;
 		client_unhide(cc);
@@ -240,9 +242,12 @@ mousefunc_menu_unhide(struct client_ctx *cc, void *arg)
 void
 mousefunc_menu_cmd(struct client_ctx *cc, void *arg)
 {
-	struct menu	*mi;
-	struct menu_q	 menuq;
-	struct cmd	*cmd;
+	struct screen_ctx	*sc;
+	struct menu		*mi;
+	struct menu_q		 menuq;
+	struct cmd		*cmd;
+
+	sc = cc->sc;
 
 	TAILQ_INIT(&menuq);
 	TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
@@ -254,7 +259,7 @@ mousefunc_menu_cmd(struct client_ctx *cc, void *arg)
 	if (TAILQ_EMPTY(&menuq))
 		return;
 
-	mi = menu_filter(&menuq, NULL, NULL, 0, NULL, NULL);
+	mi = menu_filter(sc, &menuq, NULL, NULL, 0, NULL, NULL);
 	if (mi != NULL)
 		u_spawn(((struct cmd *)mi->ctx)->image);
 	else
diff --git a/screen.c b/screen.c
index 6372362..6f73f2f 100644
--- a/screen.c
+++ b/screen.c
@@ -21,8 +21,6 @@
 #include "headers.h"
 #include "calmwm.h"
 
-extern struct screen_ctx	*Curscreen;
-
 struct screen_ctx *
 screen_fromroot(Window rootwin)
 {
@@ -36,22 +34,13 @@ screen_fromroot(Window rootwin)
 	return (TAILQ_FIRST(&Screenq));
 }
 
-struct screen_ctx *
-screen_current(void)
-{
-	return (Curscreen);
-}
-
 void
-screen_updatestackingorder(void)
+screen_updatestackingorder(struct screen_ctx *sc)
 {
 	Window			*wins, w0, w1;
-	struct screen_ctx	*sc;
 	struct client_ctx	*cc;
 	u_int			 nwins, i, s;
 
-	sc = screen_current();
-
 	if (!XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins))
 		return;
 
diff --git a/xevents.c b/xevents.c
index 8d24468..39586b1 100644
--- a/xevents.c
+++ b/xevents.c
@@ -227,7 +227,7 @@ static void
 xev_handle_buttonpress(XEvent *ee)
 {
 	XButtonEvent		*e = &ee->xbutton;
-	struct client_ctx	*cc;
+	struct client_ctx	*cc, fakecc;
 	struct screen_ctx	*sc;
 	struct mousebinding	*mb;
 
@@ -244,15 +244,13 @@ xev_handle_buttonpress(XEvent *ee)
 
 	if (mb == NULL)
 		return;
-
 	if (mb->context == MOUSEBIND_CTX_ROOT) {
 		if (e->window != sc->rootwin)
 			return;
-	} else if (mb->context == MOUSEBIND_CTX_WIN) {
-		cc = client_find(e->window);
-		if (cc == NULL)
-			return;
-	}
+		cc = &fakecc;
+		cc->sc = screen_fromroot(e->window);
+	} else if (cc == NULL) /* (mb->context == MOUSEBIND_CTX_WIN */
+		return;
 
 	(*mb->callback)(cc, e);
 }
@@ -270,7 +268,7 @@ static void
 xev_handle_keypress(XEvent *ee)
 {
 	XKeyEvent		*e = &ee->xkey;
-	struct client_ctx	*cc = NULL;
+	struct client_ctx	*cc = NULL, fakecc;
 	struct keybinding	*kb;
 	KeySym			 keysym, skeysym;
 	int			 modshift;
@@ -298,12 +296,14 @@ xev_handle_keypress(XEvent *ee)
 
 	if (kb == NULL)
 		return;
-
-	if ((kb->flags & (KBFLAG_NEEDCLIENT)) &&
-	    (cc = client_find(e->window)) == NULL &&
-	    (cc = client_current()) == NULL)
-		if (kb->flags & KBFLAG_NEEDCLIENT)
+	if (kb->flags & KBFLAG_NEEDCLIENT) {
+		if (((cc = client_find(e->window)) == NULL) &&
+		    (cc = client_current()) == NULL)
 			return;
+	} else {
+		cc = &fakecc;
+		cc->sc = screen_fromroot(e->window);
+	}
 
 	(*kb->callback)(cc, &kb->argument);
 }