mirror of
https://github.com/leahneukirchen/cwm.git
synced 2023-08-10 21:13:12 +03:00
cvsimport
This commit is contained in:
commit
9e560bd745
21
calmwm.c
21
calmwm.c
@ -48,7 +48,7 @@ struct conf Conf;
|
||||
const char *homedir;
|
||||
volatile sig_atomic_t cwm_status;
|
||||
|
||||
static void sigchld_cb(int);
|
||||
static void sighdlr(int);
|
||||
static int x_errorhandler(Display *, XErrorEvent *);
|
||||
static void x_init(const char *);
|
||||
static void x_restart(char **);
|
||||
@ -84,7 +84,7 @@ main(int argc, char **argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (signal(SIGCHLD, sigchld_cb) == SIG_ERR)
|
||||
if (signal(SIGCHLD, sighdlr) == SIG_ERR)
|
||||
err(1, "signal");
|
||||
|
||||
if ((homedir = getenv("HOME")) == NULL || *homedir == '\0') {
|
||||
@ -205,16 +205,19 @@ x_errorhandler(Display *dpy, XErrorEvent *e)
|
||||
}
|
||||
|
||||
static void
|
||||
sigchld_cb(int which)
|
||||
sighdlr(int sig)
|
||||
{
|
||||
pid_t pid;
|
||||
int save_errno = errno;
|
||||
int status;
|
||||
int save_errno = errno, status;
|
||||
|
||||
/* Collect dead children. */
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
|
||||
(pid < 0 && errno == EINTR))
|
||||
;
|
||||
switch (sig) {
|
||||
case SIGCHLD:
|
||||
/* Collect dead children. */
|
||||
while ((pid = waitpid(WAIT_ANY, &status, WNOHANG)) > 0 ||
|
||||
(pid < 0 && errno == EINTR))
|
||||
;
|
||||
break;
|
||||
}
|
||||
|
||||
errno = save_errno;
|
||||
}
|
||||
|
24
calmwm.h
24
calmwm.h
@ -199,6 +199,7 @@ struct client_ctx {
|
||||
#define CLIENT_WM_TAKE_FOCUS 0x0200
|
||||
#define CLIENT_URGENCY 0x0400
|
||||
#define CLIENT_FULLSCREEN 0x0800
|
||||
#define CLIENT_STICKY 0x1000
|
||||
|
||||
#define CLIENT_HIGHLIGHT (CLIENT_GROUP | CLIENT_UNGROUP)
|
||||
#define CLIENT_MAXFLAGS (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED)
|
||||
@ -222,10 +223,8 @@ TAILQ_HEAD(cycle_entry_q, client_ctx);
|
||||
struct group_ctx {
|
||||
TAILQ_ENTRY(group_ctx) entry;
|
||||
struct client_ctx_q clients;
|
||||
int shortcut;
|
||||
int hidden;
|
||||
int nhidden;
|
||||
int highstack;
|
||||
char *name;
|
||||
int num;
|
||||
};
|
||||
TAILQ_HEAD(group_ctx_q, group_ctx);
|
||||
|
||||
@ -263,9 +262,7 @@ struct screen_ctx {
|
||||
struct group_ctx groups[CALMWM_NGROUPS];
|
||||
struct group_ctx_q groupq;
|
||||
int group_hideall;
|
||||
int group_nonames;
|
||||
struct group_ctx *group_active;
|
||||
char **group_names;
|
||||
};
|
||||
TAILQ_HEAD(screen_ctx_q, screen_ctx);
|
||||
|
||||
@ -316,8 +313,6 @@ struct conf {
|
||||
int snapdist;
|
||||
struct gap gap;
|
||||
char *color[CWM_COLOR_NITEMS];
|
||||
char termpath[MAXPATHLEN];
|
||||
char lockpath[MAXPATHLEN];
|
||||
char known_hosts[MAXPATHLEN];
|
||||
#define CONF_FONT "sans-serif:pixelsize=14:bold"
|
||||
char *font;
|
||||
@ -371,7 +366,8 @@ enum {
|
||||
_NET_WM_DESKTOP,
|
||||
_NET_CLOSE_WINDOW,
|
||||
_NET_WM_STATE,
|
||||
#define _NET_WM_STATES_NITEMS 4
|
||||
#define _NET_WM_STATES_NITEMS 5
|
||||
_NET_WM_STATE_STICKY,
|
||||
_NET_WM_STATE_MAXIMIZED_VERT,
|
||||
_NET_WM_STATE_MAXIMIZED_HORZ,
|
||||
_NET_WM_STATE_FULLSCREEN,
|
||||
@ -418,6 +414,7 @@ void client_set_wm_state(struct client_ctx *, long);
|
||||
void client_setactive(struct client_ctx *);
|
||||
void client_setname(struct client_ctx *);
|
||||
int client_snapcalc(int, int, int, int, int);
|
||||
void client_sticky(struct client_ctx *);
|
||||
void client_transient(struct client_ctx *);
|
||||
void client_unhide(struct client_ctx *);
|
||||
void client_urgency(struct client_ctx *);
|
||||
@ -429,12 +426,13 @@ void client_wm_hints(struct client_ctx *);
|
||||
void group_alltoggle(struct screen_ctx *);
|
||||
void group_autogroup(struct client_ctx *);
|
||||
void group_cycle(struct screen_ctx *, int);
|
||||
int group_hidden_state(struct group_ctx *);
|
||||
void group_hide(struct screen_ctx *, struct group_ctx *);
|
||||
void group_hidetoggle(struct screen_ctx *, int);
|
||||
void group_init(struct screen_ctx *);
|
||||
void group_menu(struct screen_ctx *);
|
||||
void group_movetogroup(struct client_ctx *, int);
|
||||
void group_only(struct screen_ctx *, int);
|
||||
void group_set_state(struct screen_ctx *);
|
||||
void group_show(struct screen_ctx *, struct group_ctx *);
|
||||
void group_sticky(struct client_ctx *);
|
||||
void group_sticky_toggle_enter(struct client_ctx *);
|
||||
void group_sticky_toggle_exit(struct client_ctx *);
|
||||
@ -487,6 +485,7 @@ void kbfunc_client_nogroup(struct client_ctx *,
|
||||
void kbfunc_client_raise(struct client_ctx *, union arg *);
|
||||
void kbfunc_client_rcycle(struct client_ctx *, union arg *);
|
||||
void kbfunc_client_search(struct client_ctx *, union arg *);
|
||||
void kbfunc_client_sticky(struct client_ctx *, union arg *);
|
||||
void kbfunc_client_vmaximize(struct client_ctx *,
|
||||
union arg *);
|
||||
void kbfunc_cmdexec(struct client_ctx *, union arg *);
|
||||
@ -564,8 +563,7 @@ 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 *, char *,
|
||||
int);
|
||||
void xu_ewmh_net_desktop_names(struct screen_ctx *);
|
||||
|
||||
void xu_ewmh_net_wm_desktop(struct client_ctx *);
|
||||
Atom *xu_ewmh_get_net_wm_state(struct client_ctx *, int *);
|
||||
|
19
client.c
19
client.c
@ -238,6 +238,17 @@ client_freeze(struct client_ctx *cc)
|
||||
cc->flags |= CLIENT_FREEZE;
|
||||
}
|
||||
|
||||
void
|
||||
client_sticky(struct client_ctx *cc)
|
||||
{
|
||||
if (cc->flags & CLIENT_STICKY)
|
||||
cc->flags &= ~CLIENT_STICKY;
|
||||
else
|
||||
cc->flags |= CLIENT_STICKY;
|
||||
|
||||
xu_ewmh_set_net_wm_state(cc);
|
||||
}
|
||||
|
||||
void
|
||||
client_fullscreen(struct client_ctx *cc)
|
||||
{
|
||||
@ -468,6 +479,9 @@ client_ptrsave(struct client_ctx *cc)
|
||||
void
|
||||
client_hide(struct client_ctx *cc)
|
||||
{
|
||||
if (cc->flags & CLIENT_STICKY)
|
||||
return;
|
||||
|
||||
XUnmapWindow(X_Dpy, cc->win);
|
||||
|
||||
cc->active = 0;
|
||||
@ -481,6 +495,9 @@ client_hide(struct client_ctx *cc)
|
||||
void
|
||||
client_unhide(struct client_ctx *cc)
|
||||
{
|
||||
if (cc->flags & CLIENT_STICKY)
|
||||
return;
|
||||
|
||||
XMapRaised(X_Dpy, cc->win);
|
||||
|
||||
cc->flags &= ~CLIENT_HIDDEN;
|
||||
@ -869,7 +886,7 @@ client_transient(struct client_ctx *cc)
|
||||
|
||||
if (XGetTransientForHint(X_Dpy, cc->win, &trans)) {
|
||||
if ((tc = client_find(trans)) && tc->group) {
|
||||
group_movetogroup(cc, tc->group->shortcut);
|
||||
group_movetogroup(cc, tc->group->num);
|
||||
if (tc->flags & CLIENT_IGNORE)
|
||||
cc->flags |= CLIENT_IGNORE;
|
||||
}
|
||||
|
89
conf.c
89
conf.c
@ -41,27 +41,19 @@ conf_cmd_add(struct conf *c, const char *name, const char *path)
|
||||
{
|
||||
struct cmd *cmd;
|
||||
|
||||
/* "term" and "lock" have special meanings. */
|
||||
if (strcmp(name, "term") == 0) {
|
||||
if (strlcpy(c->termpath, path, sizeof(c->termpath)) >=
|
||||
sizeof(c->termpath))
|
||||
return (0);
|
||||
} else if (strcmp(name, "lock") == 0) {
|
||||
if (strlcpy(c->lockpath, path, sizeof(c->lockpath)) >=
|
||||
sizeof(c->lockpath))
|
||||
return (0);
|
||||
} else {
|
||||
conf_cmd_remove(c, name);
|
||||
cmd = xmalloc(sizeof(*cmd));
|
||||
|
||||
cmd = xmalloc(sizeof(*cmd));
|
||||
|
||||
cmd->name = xstrdup(name);
|
||||
if (strlcpy(cmd->path, path, sizeof(cmd->path)) >=
|
||||
sizeof(cmd->path))
|
||||
return (0);
|
||||
TAILQ_INSERT_TAIL(&c->cmdq, cmd, entry);
|
||||
cmd->name = xstrdup(name);
|
||||
if (strlcpy(cmd->path, path, sizeof(cmd->path)) >= sizeof(cmd->path)) {
|
||||
free(cmd->name);
|
||||
free(cmd);
|
||||
return(0);
|
||||
}
|
||||
return (1);
|
||||
|
||||
conf_cmd_remove(c, name);
|
||||
|
||||
TAILQ_INSERT_TAIL(&c->cmdq, cmd, entry);
|
||||
return(1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -78,7 +70,7 @@ conf_cmd_remove(struct conf *c, const char *name)
|
||||
}
|
||||
}
|
||||
void
|
||||
conf_autogroup(struct conf *c, int no, const char *val)
|
||||
conf_autogroup(struct conf *c, int num, const char *val)
|
||||
{
|
||||
struct autogroupwin *aw;
|
||||
char *p;
|
||||
@ -93,7 +85,7 @@ conf_autogroup(struct conf *c, int no, const char *val)
|
||||
aw->name = xstrdup(val);
|
||||
aw->class = xstrdup(p);
|
||||
}
|
||||
aw->num = no;
|
||||
aw->num = num;
|
||||
|
||||
TAILQ_INSERT_TAIL(&c->autogroupq, aw, entry);
|
||||
}
|
||||
@ -204,6 +196,7 @@ static const struct {
|
||||
{ "CM-g", "grouptoggle" },
|
||||
{ "CM-f", "fullscreen" },
|
||||
{ "CM-m", "maximize" },
|
||||
{ "CM-s", "sticky" },
|
||||
{ "CM-equal", "vmaximize" },
|
||||
{ "CMS-equal", "hmaximize" },
|
||||
{ "CMS-f", "freeze" },
|
||||
@ -250,8 +243,6 @@ conf_init(struct conf *c)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
(void)memset(c, 0, sizeof(*c));
|
||||
|
||||
c->bwidth = CONF_BWIDTH;
|
||||
c->mamount = CONF_MAMOUNT;
|
||||
c->snapdist = CONF_SNAPDIST;
|
||||
@ -346,7 +337,7 @@ static const struct {
|
||||
void (*handler)(struct client_ctx *, union arg *);
|
||||
int flags;
|
||||
union arg argument;
|
||||
} name_to_kbfunc[] = {
|
||||
} name_to_func[] = {
|
||||
{ "lower", kbfunc_client_lower, CWM_WIN, {0} },
|
||||
{ "raise", kbfunc_client_raise, CWM_WIN, {0} },
|
||||
{ "search", kbfunc_client_search, 0, {0} },
|
||||
@ -391,6 +382,7 @@ static const struct {
|
||||
{ "rcycleingroup", kbfunc_client_cycle, CWM_WIN,
|
||||
{.i = CWM_RCYCLE|CWM_INGROUP} },
|
||||
{ "grouptoggle", kbfunc_client_grouptoggle, CWM_WIN, {0}},
|
||||
{ "sticky", kbfunc_client_sticky, CWM_WIN, {0} },
|
||||
{ "fullscreen", kbfunc_client_fullscreen, CWM_WIN, {0} },
|
||||
{ "maximize", kbfunc_client_maximize, CWM_WIN, {0} },
|
||||
{ "vmaximize", kbfunc_client_vmaximize, CWM_WIN, {0} },
|
||||
@ -453,6 +445,15 @@ static const struct {
|
||||
{.i = (CWM_RIGHT|CWM_PTRMOVE|CWM_BIGMOVE)} },
|
||||
{ "htile", kbfunc_tile, CWM_WIN, {.i = CWM_TILE_HORIZ} },
|
||||
{ "vtile", kbfunc_tile, CWM_WIN, {.i = CWM_TILE_VERT} },
|
||||
{ "window_lower", kbfunc_client_lower, CWM_WIN, {0} },
|
||||
{ "window_raise", kbfunc_client_raise, CWM_WIN, {0} },
|
||||
{ "window_hide", kbfunc_client_hide, CWM_WIN, {0} },
|
||||
{ "window_move", mousefunc_client_move, CWM_WIN, {0} },
|
||||
{ "window_resize", mousefunc_client_resize, CWM_WIN, {0} },
|
||||
{ "window_grouptoggle", mousefunc_client_grouptoggle, CWM_WIN, {0} },
|
||||
{ "menu_group", mousefunc_menu_group, 0, {0} },
|
||||
{ "menu_unhide", mousefunc_menu_unhide, 0, {0} },
|
||||
{ "menu_cmd", mousefunc_menu_cmd, 0, {0} },
|
||||
};
|
||||
|
||||
static const struct {
|
||||
@ -510,13 +511,13 @@ conf_bind_kbd(struct conf *c, const char *bind, const char *cmd)
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (i = 0; i < nitems(name_to_kbfunc); i++) {
|
||||
if (strcmp(name_to_kbfunc[i].tag, cmd) != 0)
|
||||
for (i = 0; i < nitems(name_to_func); i++) {
|
||||
if (strcmp(name_to_func[i].tag, cmd) != 0)
|
||||
continue;
|
||||
|
||||
kb->callback = name_to_kbfunc[i].handler;
|
||||
kb->flags = name_to_kbfunc[i].flags;
|
||||
kb->argument = name_to_kbfunc[i].argument;
|
||||
kb->callback = name_to_func[i].handler;
|
||||
kb->flags = name_to_func[i].flags;
|
||||
kb->argument = name_to_func[i].argument;
|
||||
kb->argtype |= ARG_INT;
|
||||
TAILQ_INSERT_TAIL(&c->keybindingq, kb, entry);
|
||||
return (1);
|
||||
@ -548,25 +549,6 @@ conf_unbind_kbd(struct conf *c, struct binding *unbind)
|
||||
}
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *tag;
|
||||
void (*handler)(struct client_ctx *, union arg *);
|
||||
int flags;
|
||||
union arg argument;
|
||||
} name_to_mousefunc[] = {
|
||||
{ "window_lower", kbfunc_client_lower, CWM_WIN, {0} },
|
||||
{ "window_raise", kbfunc_client_raise, CWM_WIN, {0} },
|
||||
{ "window_hide", kbfunc_client_hide, CWM_WIN, {0} },
|
||||
{ "cyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_CYCLE} },
|
||||
{ "rcyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_RCYCLE} },
|
||||
{ "window_move", mousefunc_client_move, CWM_WIN, {0} },
|
||||
{ "window_resize", mousefunc_client_resize, CWM_WIN, {0} },
|
||||
{ "window_grouptoggle", mousefunc_client_grouptoggle, CWM_WIN, {0} },
|
||||
{ "menu_group", mousefunc_menu_group, 0, {0} },
|
||||
{ "menu_unhide", mousefunc_menu_unhide, 0, {0} },
|
||||
{ "menu_cmd", mousefunc_menu_cmd, 0, {0} },
|
||||
};
|
||||
|
||||
int
|
||||
conf_bind_mouse(struct conf *c, const char *bind, const char *cmd)
|
||||
{
|
||||
@ -593,13 +575,13 @@ conf_bind_mouse(struct conf *c, const char *bind, const char *cmd)
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (i = 0; i < nitems(name_to_mousefunc); i++) {
|
||||
if (strcmp(name_to_mousefunc[i].tag, cmd) != 0)
|
||||
for (i = 0; i < nitems(name_to_func); i++) {
|
||||
if (strcmp(name_to_func[i].tag, cmd) != 0)
|
||||
continue;
|
||||
|
||||
mb->callback = name_to_mousefunc[i].handler;
|
||||
mb->flags = name_to_mousefunc[i].flags;
|
||||
mb->argument = name_to_mousefunc[i].argument;
|
||||
mb->callback = name_to_func[i].handler;
|
||||
mb->flags = name_to_func[i].flags;
|
||||
mb->argument = name_to_func[i].argument;
|
||||
TAILQ_INSERT_TAIL(&c->mousebindingq, mb, entry);
|
||||
return (1);
|
||||
}
|
||||
@ -690,6 +672,7 @@ static char *ewmhints[] = {
|
||||
"_NET_WM_DESKTOP",
|
||||
"_NET_CLOSE_WINDOW",
|
||||
"_NET_WM_STATE",
|
||||
"_NET_WM_STATE_STICKY",
|
||||
"_NET_WM_STATE_MAXIMIZED_VERT",
|
||||
"_NET_WM_STATE_MAXIMIZED_HORZ",
|
||||
"_NET_WM_STATE_FULLSCREEN",
|
||||
|
4
cwm.1
4
cwm.1
@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: December 16 2013 $
|
||||
.Dd $Mdocdate$
|
||||
.Dt CWM 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -90,6 +90,8 @@ Cycle through active groups.
|
||||
Reverse cycle through active groups.
|
||||
.It Ic CMS-f
|
||||
Toggle freezing geometry of current window.
|
||||
.It Ic CM-s
|
||||
Toggle stickiness of current window.
|
||||
.It Ic CM-f
|
||||
Toggle full-screen mode of current window.
|
||||
.It Ic CM-m
|
||||
|
4
cwmrc.5
4
cwmrc.5
@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: December 16 2013 $
|
||||
.Dd $Mdocdate$
|
||||
.Dt CWMRC 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -341,6 +341,8 @@ Raise current window.
|
||||
Label current window.
|
||||
.It freeze
|
||||
Freeze current window geometry.
|
||||
.It sticky
|
||||
Stick current window to all groups (same as assigning to nogroup).
|
||||
.It fullscreen
|
||||
Full-screen current window (gap + border removed).
|
||||
.It maximize
|
||||
|
241
group.c
241
group.c
@ -33,13 +33,10 @@
|
||||
#include "calmwm.h"
|
||||
|
||||
static void group_assign(struct group_ctx *, struct client_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 *);
|
||||
static void group_restack(struct screen_ctx *, struct group_ctx *);
|
||||
static void group_setactive(struct screen_ctx *, long);
|
||||
static void group_set_names(struct screen_ctx *);
|
||||
|
||||
const char *shortcut_to_name[] = {
|
||||
const char *num_to_name[] = {
|
||||
"nogroup", "one", "two", "three", "four", "five", "six",
|
||||
"seven", "eight", "nine"
|
||||
};
|
||||
@ -47,63 +44,62 @@ const char *shortcut_to_name[] = {
|
||||
static void
|
||||
group_assign(struct group_ctx *gc, struct client_ctx *cc)
|
||||
{
|
||||
if (gc == NULL)
|
||||
gc = TAILQ_FIRST(&cc->sc->groupq);
|
||||
if (cc->group == gc)
|
||||
return;
|
||||
|
||||
if (cc->group != NULL)
|
||||
TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
|
||||
|
||||
TAILQ_INSERT_TAIL(&gc->clients, cc, group_entry);
|
||||
cc->group = gc;
|
||||
|
||||
if (cc->group != NULL)
|
||||
TAILQ_INSERT_TAIL(&gc->clients, cc, group_entry);
|
||||
|
||||
xu_ewmh_net_wm_desktop(cc);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
group_hide(struct screen_ctx *sc, struct group_ctx *gc)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
|
||||
screen_updatestackingorder(sc);
|
||||
|
||||
gc->nhidden = 0;
|
||||
gc->highstack = 0;
|
||||
TAILQ_FOREACH(cc, &gc->clients, group_entry) {
|
||||
TAILQ_FOREACH(cc, &gc->clients, group_entry)
|
||||
client_hide(cc);
|
||||
gc->nhidden++;
|
||||
if (cc->stackingorder > gc->highstack)
|
||||
gc->highstack = cc->stackingorder;
|
||||
}
|
||||
gc->hidden = 1; /* XXX: equivalent to gc->nhidden > 0 */
|
||||
}
|
||||
|
||||
void
|
||||
group_show(struct screen_ctx *sc, struct group_ctx *gc)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
|
||||
TAILQ_FOREACH(cc, &gc->clients, group_entry)
|
||||
client_unhide(cc);
|
||||
|
||||
group_restack(sc, gc);
|
||||
group_setactive(sc, gc->num);
|
||||
}
|
||||
|
||||
static void
|
||||
group_show(struct screen_ctx *sc, struct group_ctx *gc)
|
||||
group_restack(struct screen_ctx *sc, struct group_ctx *gc)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
Window *winlist;
|
||||
int i, lastempty = -1;
|
||||
int nwins = 0, highstack = 0;
|
||||
|
||||
gc->highstack = 0;
|
||||
TAILQ_FOREACH(cc, &gc->clients, group_entry) {
|
||||
if (cc->stackingorder > gc->highstack)
|
||||
gc->highstack = cc->stackingorder;
|
||||
if (cc->stackingorder > highstack)
|
||||
highstack = cc->stackingorder;
|
||||
}
|
||||
winlist = xcalloc((gc->highstack + 1), sizeof(*winlist));
|
||||
winlist = xcalloc((highstack + 1), sizeof(*winlist));
|
||||
|
||||
/*
|
||||
* Invert the stacking order as XRestackWindows() expects them
|
||||
* top-to-bottom.
|
||||
*/
|
||||
/* Invert the stacking order for XRestackWindows(). */
|
||||
TAILQ_FOREACH(cc, &gc->clients, group_entry) {
|
||||
winlist[gc->highstack - cc->stackingorder] = cc->win;
|
||||
client_unhide(cc);
|
||||
winlist[highstack - cc->stackingorder] = cc->win;
|
||||
nwins++;
|
||||
}
|
||||
|
||||
/* Un-sparseify */
|
||||
for (i = 0; i <= gc->highstack; i++) {
|
||||
for (i = 0; i <= highstack; i++) {
|
||||
if (!winlist[i] && lastempty == -1)
|
||||
lastempty = i;
|
||||
else if (winlist[i] && lastempty != -1) {
|
||||
@ -113,11 +109,8 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc)
|
||||
}
|
||||
}
|
||||
|
||||
XRestackWindows(X_Dpy, winlist, gc->nhidden);
|
||||
XRestackWindows(X_Dpy, winlist, nwins);
|
||||
free(winlist);
|
||||
|
||||
gc->hidden = 0;
|
||||
group_setactive(sc, gc->shortcut);
|
||||
}
|
||||
|
||||
void
|
||||
@ -127,19 +120,15 @@ group_init(struct screen_ctx *sc)
|
||||
|
||||
TAILQ_INIT(&sc->groupq);
|
||||
sc->group_hideall = 0;
|
||||
/*
|
||||
* See if any group names have already been set and update the
|
||||
* property with ours if they'll have changed.
|
||||
*/
|
||||
group_update_names(sc);
|
||||
|
||||
for (i = 0; i < CALMWM_NGROUPS; i++) {
|
||||
TAILQ_INIT(&sc->groups[i].clients);
|
||||
sc->groups[i].hidden = 0;
|
||||
sc->groups[i].shortcut = i;
|
||||
sc->groups[i].name = xstrdup(num_to_name[i]);
|
||||
sc->groups[i].num = i;
|
||||
TAILQ_INSERT_TAIL(&sc->groupq, &sc->groups[i], entry);
|
||||
}
|
||||
|
||||
xu_ewmh_net_desktop_names(sc);
|
||||
xu_ewmh_net_wm_desktop_viewport(sc);
|
||||
xu_ewmh_net_wm_number_of_desktops(sc);
|
||||
xu_ewmh_net_showing_desktop(sc);
|
||||
@ -148,15 +137,6 @@ group_init(struct screen_ctx *sc)
|
||||
group_setactive(sc, 1);
|
||||
}
|
||||
|
||||
void
|
||||
group_set_state(struct screen_ctx *sc)
|
||||
{
|
||||
struct group_ctx *gc;
|
||||
|
||||
TAILQ_FOREACH(gc, &sc->groupq, entry)
|
||||
group_fix_hidden_state(gc);
|
||||
}
|
||||
|
||||
static void
|
||||
group_setactive(struct screen_ctx *sc, long idx)
|
||||
{
|
||||
@ -175,12 +155,11 @@ group_movetogroup(struct client_ctx *cc, int idx)
|
||||
errx(1, "group_movetogroup: index out of range (%d)", idx);
|
||||
|
||||
gc = &sc->groups[idx];
|
||||
|
||||
if (cc->group == gc)
|
||||
return;
|
||||
if (gc->hidden) {
|
||||
if (group_hidden_state(gc))
|
||||
client_hide(cc);
|
||||
gc->nhidden++;
|
||||
}
|
||||
group_assign(gc, cc);
|
||||
}
|
||||
|
||||
@ -212,21 +191,25 @@ group_sticky_toggle_exit(struct client_ctx *cc)
|
||||
}
|
||||
|
||||
/*
|
||||
* if group_hidetoggle would produce no effect, toggle the group's hidden state
|
||||
* If all clients in a group are hidden, then the group state is hidden.
|
||||
*/
|
||||
static void
|
||||
group_fix_hidden_state(struct group_ctx *gc)
|
||||
int
|
||||
group_hidden_state(struct group_ctx *gc)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
int same = 0;
|
||||
int hidden = 0, same = 0;
|
||||
|
||||
TAILQ_FOREACH(cc, &gc->clients, group_entry) {
|
||||
if (gc->hidden == ((cc->flags & CLIENT_HIDDEN) ? 1 : 0))
|
||||
if (cc->flags & CLIENT_STICKY)
|
||||
continue;
|
||||
if (hidden == ((cc->flags & CLIENT_HIDDEN) ? 1 : 0))
|
||||
same++;
|
||||
}
|
||||
|
||||
if (same == 0)
|
||||
gc->hidden = !gc->hidden;
|
||||
hidden = !hidden;
|
||||
|
||||
return(hidden);
|
||||
}
|
||||
|
||||
void
|
||||
@ -238,9 +221,8 @@ group_hidetoggle(struct screen_ctx *sc, int idx)
|
||||
errx(1, "group_hidetoggle: index out of range (%d)", idx);
|
||||
|
||||
gc = &sc->groups[idx];
|
||||
group_fix_hidden_state(gc);
|
||||
|
||||
if (gc->hidden)
|
||||
if (group_hidden_state(gc))
|
||||
group_show(sc, gc);
|
||||
else {
|
||||
group_hide(sc, gc);
|
||||
@ -259,7 +241,7 @@ group_only(struct screen_ctx *sc, int idx)
|
||||
errx(1, "group_only: index out of range (%d)", idx);
|
||||
|
||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||
if (gc->shortcut == idx)
|
||||
if (gc->num == idx)
|
||||
group_show(sc, gc);
|
||||
else
|
||||
group_hide(sc, gc);
|
||||
@ -288,7 +270,7 @@ group_cycle(struct screen_ctx *sc, int flags)
|
||||
|
||||
if (!TAILQ_EMPTY(&gc->clients) && showgroup == NULL)
|
||||
showgroup = gc;
|
||||
else if (!gc->hidden)
|
||||
else if (!group_hidden_state(gc))
|
||||
group_hide(sc, gc);
|
||||
}
|
||||
|
||||
@ -297,39 +279,10 @@ group_cycle(struct screen_ctx *sc, int flags)
|
||||
|
||||
group_hide(sc, sc->group_active);
|
||||
|
||||
if (showgroup->hidden)
|
||||
if (group_hidden_state(showgroup))
|
||||
group_show(sc, showgroup);
|
||||
else
|
||||
group_setactive(sc, showgroup->shortcut);
|
||||
}
|
||||
|
||||
void
|
||||
group_menu(struct screen_ctx *sc)
|
||||
{
|
||||
struct group_ctx *gc;
|
||||
struct menu *mi;
|
||||
struct menu_q menuq;
|
||||
|
||||
TAILQ_INIT(&menuq);
|
||||
|
||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||
if (TAILQ_EMPTY(&gc->clients))
|
||||
continue;
|
||||
|
||||
menuq_add(&menuq, gc, gc->hidden ? "%d: [%s]" : "%d: %s",
|
||||
gc->shortcut, sc->group_names[gc->shortcut]);
|
||||
}
|
||||
|
||||
if (TAILQ_EMPTY(&menuq))
|
||||
return;
|
||||
|
||||
mi = menu_filter(sc, &menuq, NULL, NULL, 0, NULL, NULL);
|
||||
if (mi != NULL && mi->ctx != NULL) {
|
||||
gc = (struct group_ctx *)mi->ctx;
|
||||
(gc->hidden) ? group_show(sc, gc) : group_hide(sc, gc);
|
||||
}
|
||||
|
||||
menuq_clear(&menuq);
|
||||
group_setactive(sc, showgroup->num);
|
||||
}
|
||||
|
||||
void
|
||||
@ -352,36 +305,38 @@ group_autogroup(struct client_ctx *cc)
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct autogroupwin *aw;
|
||||
struct group_ctx *gc;
|
||||
int no = -1, both_match = 0;
|
||||
long *grpno;
|
||||
int num = -2, both_match = 0;
|
||||
long *grpnum;
|
||||
|
||||
if (cc->ch.res_class == NULL || cc->ch.res_name == NULL)
|
||||
return;
|
||||
|
||||
if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP],
|
||||
XA_CARDINAL, 1, (unsigned char **)&grpno) > 0) {
|
||||
if (*grpno == -1)
|
||||
no = 0;
|
||||
else if (*grpno > CALMWM_NGROUPS || *grpno < 0)
|
||||
no = CALMWM_NGROUPS - 1;
|
||||
else
|
||||
no = *grpno;
|
||||
XFree(grpno);
|
||||
XA_CARDINAL, 1, (unsigned char **)&grpnum) > 0) {
|
||||
num = *grpnum;
|
||||
if (num > CALMWM_NGROUPS || num < -1)
|
||||
num = CALMWM_NGROUPS - 1;
|
||||
XFree(grpnum);
|
||||
} else {
|
||||
TAILQ_FOREACH(aw, &Conf.autogroupq, entry) {
|
||||
if (strcmp(aw->class, cc->ch.res_class) == 0) {
|
||||
if ((aw->name != NULL) &&
|
||||
(strcmp(aw->name, cc->ch.res_name) == 0)) {
|
||||
no = aw->num;
|
||||
num = aw->num;
|
||||
both_match = 1;
|
||||
} else if (aw->name == NULL && !both_match)
|
||||
no = aw->num;
|
||||
num = aw->num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((num == -1) || (num == 0)) {
|
||||
group_assign(NULL, cc);
|
||||
return;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||
if (gc->shortcut == no) {
|
||||
if (gc->num == num) {
|
||||
group_assign(gc, cc);
|
||||
return;
|
||||
}
|
||||
@ -392,71 +347,3 @@ group_autogroup(struct client_ctx *cc)
|
||||
else
|
||||
group_assign(NULL, cc);
|
||||
}
|
||||
|
||||
void
|
||||
group_update_names(struct screen_ctx *sc)
|
||||
{
|
||||
char **strings, *p;
|
||||
unsigned char *prop_ret;
|
||||
int i = 0, j = 0, nstrings = 0, n = 0, setnames = 0;
|
||||
|
||||
if ((j = xu_getprop(sc->rootwin, ewmh[_NET_DESKTOP_NAMES],
|
||||
cwmh[UTF8_STRING], 0xffffff, (unsigned char **)&prop_ret)) > 0) {
|
||||
prop_ret[j - 1] = '\0'; /* paranoia */
|
||||
while (i < j) {
|
||||
if (prop_ret[i++] == '\0')
|
||||
nstrings++;
|
||||
}
|
||||
}
|
||||
|
||||
strings = xcalloc((nstrings < CALMWM_NGROUPS ? CALMWM_NGROUPS :
|
||||
nstrings), sizeof(*strings));
|
||||
|
||||
p = (char *)prop_ret;
|
||||
while (n < nstrings) {
|
||||
strings[n++] = xstrdup(p);
|
||||
p += strlen(p) + 1;
|
||||
}
|
||||
/*
|
||||
* make sure we always set our defaults if nothing is there to
|
||||
* replace them.
|
||||
*/
|
||||
if (n < CALMWM_NGROUPS) {
|
||||
setnames = 1;
|
||||
i = 0;
|
||||
while (n < CALMWM_NGROUPS)
|
||||
strings[n++] = xstrdup(shortcut_to_name[i++]);
|
||||
}
|
||||
|
||||
if (prop_ret != NULL)
|
||||
XFree(prop_ret);
|
||||
if (sc->group_nonames != 0)
|
||||
free(sc->group_names);
|
||||
|
||||
sc->group_names = strings;
|
||||
sc->group_nonames = n;
|
||||
if (setnames)
|
||||
group_set_names(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
group_set_names(struct screen_ctx *sc)
|
||||
{
|
||||
char *p, *q;
|
||||
size_t len = 0, tlen, slen;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sc->group_nonames; i++)
|
||||
len += strlen(sc->group_names[i]) + 1;
|
||||
q = p = xcalloc(len, sizeof(*p));
|
||||
|
||||
tlen = len;
|
||||
for (i = 0; i < sc->group_nonames; i++) {
|
||||
slen = strlen(sc->group_names[i]) + 1;
|
||||
(void)strlcpy(q, sc->group_names[i], tlen);
|
||||
tlen -= slen;
|
||||
q += slen;
|
||||
}
|
||||
|
||||
xu_ewmh_net_desktop_names(sc, p, len);
|
||||
}
|
||||
|
37
kbfunc.c
37
kbfunc.c
@ -159,7 +159,6 @@ kbfunc_client_search(struct client_ctx *cc, union arg *arg)
|
||||
cc = (struct client_ctx *)mi->ctx;
|
||||
if (cc->flags & CLIENT_HIDDEN)
|
||||
client_unhide(cc);
|
||||
|
||||
if (old_cc)
|
||||
client_ptrsave(old_cc);
|
||||
client_ptrwarp(cc);
|
||||
@ -214,13 +213,23 @@ kbfunc_cmdexec(struct client_ctx *cc, union arg *arg)
|
||||
void
|
||||
kbfunc_term(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
u_spawn(Conf.termpath);
|
||||
struct cmd *cmd;
|
||||
|
||||
TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
|
||||
if (strcmp(cmd->name, "term") == 0)
|
||||
u_spawn(cmd->path);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_lock(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
u_spawn(Conf.lockpath);
|
||||
struct cmd *cmd;
|
||||
|
||||
TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
|
||||
if (strcmp(cmd->name, "lock") == 0)
|
||||
u_spawn(cmd->path);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -310,12 +319,13 @@ void
|
||||
kbfunc_ssh(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct cmd *cmd;
|
||||
struct menu *mi;
|
||||
struct menu_q menuq;
|
||||
FILE *fp;
|
||||
char *buf, *lbuf, *p;
|
||||
char hostbuf[MAXHOSTNAMELEN];
|
||||
char cmd[256];
|
||||
char path[MAXPATHLEN];
|
||||
int l;
|
||||
size_t len;
|
||||
|
||||
@ -324,6 +334,11 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg)
|
||||
return;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
|
||||
if (strcmp(cmd->name, "term") == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
TAILQ_INIT(&menuq);
|
||||
|
||||
lbuf = NULL;
|
||||
@ -356,10 +371,10 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg)
|
||||
search_match_exec, NULL)) != NULL) {
|
||||
if (mi->text[0] == '\0')
|
||||
goto out;
|
||||
l = snprintf(cmd, sizeof(cmd), "%s -T '[ssh] %s' -e ssh %s",
|
||||
Conf.termpath, mi->text, mi->text);
|
||||
if (l != -1 && l < sizeof(cmd))
|
||||
u_spawn(cmd);
|
||||
l = snprintf(path, sizeof(path), "%s -T '[ssh] %s' -e ssh %s",
|
||||
cmd->path, mi->text, mi->text);
|
||||
if (l != -1 && l < sizeof(path))
|
||||
u_spawn(path);
|
||||
}
|
||||
out:
|
||||
if (mi != NULL && mi->dummy)
|
||||
@ -432,6 +447,12 @@ kbfunc_client_movetogroup(struct client_ctx *cc, union arg *arg)
|
||||
group_movetogroup(cc, arg->i);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_sticky(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
client_sticky(cc);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_fullscreen(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
|
4
menu.c
4
menu.c
@ -260,7 +260,7 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
|
||||
* even if dummy is zero, we need to return something.
|
||||
*/
|
||||
if ((mi = TAILQ_FIRST(resultq)) == NULL) {
|
||||
mi = xmalloc(sizeof *mi);
|
||||
mi = xmalloc(sizeof(*mi));
|
||||
(void)strlcpy(mi->text,
|
||||
mc->searchstr, sizeof(mi->text));
|
||||
mi->dummy = 1;
|
||||
@ -302,7 +302,7 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
|
||||
mc->list = !mc->list;
|
||||
break;
|
||||
case CTL_ABORT:
|
||||
mi = xmalloc(sizeof *mi);
|
||||
mi = xmalloc(sizeof(*mi));
|
||||
mi->text[0] = '\0';
|
||||
mi->dummy = 1;
|
||||
mi->abort = 1;
|
||||
|
34
mousefunc.c
34
mousefunc.c
@ -181,7 +181,30 @@ mousefunc_client_grouptoggle(struct client_ctx *cc, union arg *arg)
|
||||
void
|
||||
mousefunc_menu_group(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
group_menu(cc->sc);
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct group_ctx *gc;
|
||||
struct menu *mi;
|
||||
struct menu_q menuq;
|
||||
|
||||
TAILQ_INIT(&menuq);
|
||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||
if (TAILQ_EMPTY(&gc->clients))
|
||||
continue;
|
||||
menuq_add(&menuq, gc,
|
||||
group_hidden_state(gc) ? "%d: [%s]" : "%d: %s",
|
||||
gc->num, gc->name);
|
||||
}
|
||||
if (TAILQ_EMPTY(&menuq))
|
||||
return;
|
||||
|
||||
if ((mi = menu_filter(sc, &menuq, NULL, NULL, 0,
|
||||
NULL, NULL)) != NULL) {
|
||||
gc = (struct group_ctx *)mi->ctx;
|
||||
(group_hidden_state(gc)) ?
|
||||
group_show(sc, gc) : group_hide(sc, gc);
|
||||
}
|
||||
|
||||
menuq_clear(&menuq);
|
||||
}
|
||||
|
||||
void
|
||||
@ -196,16 +219,15 @@ mousefunc_menu_unhide(struct client_ctx *cc, union arg *arg)
|
||||
old_cc = client_current();
|
||||
|
||||
TAILQ_INIT(&menuq);
|
||||
TAILQ_FOREACH(cc, &Clientq, entry)
|
||||
TAILQ_FOREACH(cc, &Clientq, entry) {
|
||||
if (cc->flags & CLIENT_HIDDEN) {
|
||||
wname = (cc->label) ? cc->label : cc->name;
|
||||
if (wname == NULL)
|
||||
continue;
|
||||
|
||||
menuq_add(&menuq, cc, "(%d) %s",
|
||||
cc->group->shortcut, wname);
|
||||
cc->group ? cc->group->num : 0, wname);
|
||||
}
|
||||
|
||||
}
|
||||
if (TAILQ_EMPTY(&menuq))
|
||||
return;
|
||||
|
||||
@ -213,7 +235,6 @@ mousefunc_menu_unhide(struct client_ctx *cc, union arg *arg)
|
||||
NULL, NULL)) != NULL) {
|
||||
cc = (struct client_ctx *)mi->ctx;
|
||||
client_unhide(cc);
|
||||
|
||||
if (old_cc != NULL)
|
||||
client_ptrsave(old_cc);
|
||||
client_ptrwarp(cc);
|
||||
@ -233,7 +254,6 @@ mousefunc_menu_cmd(struct client_ctx *cc, union arg *arg)
|
||||
TAILQ_INIT(&menuq);
|
||||
TAILQ_FOREACH(cmd, &Conf.cmdq, entry)
|
||||
menuq_add(&menuq, cmd, "%s", cmd->name);
|
||||
|
||||
if (TAILQ_EMPTY(&menuq))
|
||||
return;
|
||||
|
||||
|
7
screen.c
7
screen.c
@ -69,7 +69,6 @@ screen_init(int which)
|
||||
XFree(wins);
|
||||
}
|
||||
screen_updatestackingorder(sc);
|
||||
group_set_state(sc);
|
||||
|
||||
if (HasRandr)
|
||||
XRRSelectInput(X_Dpy, sc->rootwin, RRScreenChangeNotifyMask);
|
||||
@ -142,7 +141,7 @@ screen_update_geometry(struct screen_ctx *sc)
|
||||
{
|
||||
XineramaScreenInfo *info = NULL;
|
||||
struct region_ctx *region;
|
||||
int info_no = 0, i;
|
||||
int info_num = 0, i;
|
||||
|
||||
sc->view.x = 0;
|
||||
sc->view.y = 0;
|
||||
@ -156,13 +155,13 @@ screen_update_geometry(struct screen_ctx *sc)
|
||||
|
||||
/* RandR event may have a CTRC added or removed. */
|
||||
if (XineramaIsActive(X_Dpy))
|
||||
info = XineramaQueryScreens(X_Dpy, &info_no);
|
||||
info = XineramaQueryScreens(X_Dpy, &info_num);
|
||||
|
||||
while ((region = TAILQ_FIRST(&sc->regionq)) != NULL) {
|
||||
TAILQ_REMOVE(&sc->regionq, region, entry);
|
||||
free(region);
|
||||
}
|
||||
for (i = 0; i < info_no; i++) {
|
||||
for (i = 0; i < info_num; i++) {
|
||||
region = xmalloc(sizeof(*region));
|
||||
region->num = i;
|
||||
region->area.x = info[i].x_org;
|
||||
|
2
search.c
2
search.c
@ -143,7 +143,7 @@ search_print_client(struct menu *mi, int list)
|
||||
cc->matchname = cc->name;
|
||||
|
||||
(void)snprintf(mi->print, sizeof(mi->print), "(%d) %c%s",
|
||||
cc->group->shortcut, flag, cc->matchname);
|
||||
cc->group ? cc->group->num : 0, flag, cc->matchname);
|
||||
|
||||
if (!list && cc->matchname != cc->name &&
|
||||
strlen(mi->print) < sizeof(mi->print) - 1) {
|
||||
|
@ -196,7 +196,7 @@ xev_handle_propertynotify(XEvent *ee)
|
||||
TAILQ_FOREACH(sc, &Screenq, entry) {
|
||||
if (sc->rootwin == e->window) {
|
||||
if (e->atom == ewmh[_NET_DESKTOP_NAMES])
|
||||
group_update_names(sc);
|
||||
xu_ewmh_net_desktop_names(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
63
xutil.c
63
xutil.c
@ -281,20 +281,67 @@ xu_ewmh_net_current_desktop(struct screen_ctx *sc, long idx)
|
||||
}
|
||||
|
||||
void
|
||||
xu_ewmh_net_desktop_names(struct screen_ctx *sc, char *data, int n)
|
||||
xu_ewmh_net_desktop_names(struct screen_ctx *sc)
|
||||
{
|
||||
struct group_ctx *gc;
|
||||
char *p, *q;
|
||||
unsigned char *prop_ret;
|
||||
int i = 0, j = 0, nstrings = 0, n = 0;
|
||||
size_t len = 0, tlen, slen;
|
||||
|
||||
/* Let group names be overwritten if _NET_DESKTOP_NAMES is set. */
|
||||
|
||||
if ((j = xu_getprop(sc->rootwin, ewmh[_NET_DESKTOP_NAMES],
|
||||
cwmh[UTF8_STRING], 0xffffff, (unsigned char **)&prop_ret)) > 0) {
|
||||
prop_ret[j - 1] = '\0'; /* paranoia */
|
||||
while (i < j) {
|
||||
if (prop_ret[i++] == '\0')
|
||||
nstrings++;
|
||||
}
|
||||
}
|
||||
|
||||
p = (char *)prop_ret;
|
||||
while (n < nstrings) {
|
||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||
if (gc->num == n) {
|
||||
free(gc->name);
|
||||
gc->name = xstrdup(p);
|
||||
p += strlen(p) + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
n++;
|
||||
}
|
||||
if (prop_ret != NULL)
|
||||
XFree(prop_ret);
|
||||
|
||||
TAILQ_FOREACH(gc, &sc->groupq, entry)
|
||||
len += strlen(gc->name) + 1;
|
||||
q = p = xcalloc(len, sizeof(*p));
|
||||
|
||||
tlen = len;
|
||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||
slen = strlen(gc->name) + 1;
|
||||
(void)strlcpy(q, gc->name, tlen);
|
||||
tlen -= slen;
|
||||
q += slen;
|
||||
}
|
||||
|
||||
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_NAMES],
|
||||
cwmh[UTF8_STRING], 8, PropModeReplace, (unsigned char *)data, n);
|
||||
cwmh[UTF8_STRING], 8, PropModeReplace, (unsigned char *)p, len);
|
||||
}
|
||||
|
||||
/* Application Window Properties */
|
||||
void
|
||||
xu_ewmh_net_wm_desktop(struct client_ctx *cc)
|
||||
{
|
||||
long no = cc->group->shortcut;
|
||||
long num = 0xffffffff;
|
||||
|
||||
if (cc->group)
|
||||
num = cc->group->num;
|
||||
|
||||
XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_DESKTOP],
|
||||
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&no, 1);
|
||||
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&num, 1);
|
||||
}
|
||||
|
||||
Atom *
|
||||
@ -323,6 +370,9 @@ xu_ewmh_handle_net_wm_state_msg(struct client_ctx *cc, int action,
|
||||
int property;
|
||||
void (*toggle)(struct client_ctx *);
|
||||
} handlers[] = {
|
||||
{ _NET_WM_STATE_STICKY,
|
||||
CLIENT_STICKY,
|
||||
client_sticky },
|
||||
{ _NET_WM_STATE_MAXIMIZED_VERT,
|
||||
CLIENT_VMAXIMIZED,
|
||||
client_vmaximize },
|
||||
@ -364,6 +414,8 @@ xu_ewmh_restore_net_wm_state(struct client_ctx *cc)
|
||||
|
||||
atoms = xu_ewmh_get_net_wm_state(cc, &n);
|
||||
for (i = 0; i < n; i++) {
|
||||
if (atoms[i] == ewmh[_NET_WM_STATE_STICKY])
|
||||
client_sticky(cc);
|
||||
if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_HORZ])
|
||||
client_hmaximize(cc);
|
||||
if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_VERT])
|
||||
@ -388,10 +440,13 @@ xu_ewmh_set_net_wm_state(struct client_ctx *cc)
|
||||
if (oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_HORZ] &&
|
||||
oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_VERT] &&
|
||||
oatoms[i] != ewmh[_NET_WM_STATE_FULLSCREEN] &&
|
||||
oatoms[i] != ewmh[_NET_WM_STATE_STICKY] &&
|
||||
oatoms[i] != ewmh[_NET_WM_STATE_DEMANDS_ATTENTION])
|
||||
atoms[j++] = oatoms[i];
|
||||
}
|
||||
free(oatoms);
|
||||
if (cc->flags & CLIENT_STICKY)
|
||||
atoms[j++] = ewmh[_NET_WM_STATE_STICKY];
|
||||
if (cc->flags & CLIENT_FULLSCREEN)
|
||||
atoms[j++] = ewmh[_NET_WM_STATE_FULLSCREEN];
|
||||
else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user