Compare commits

..

17 Commits
v6.7 ... linux

Author SHA1 Message Date
op
73cef0ffb0 cvsimport
* refs/heads/master:
  cwm: fix a semi-transparency border issue with some applications
2023-03-22 08:27:36 +00:00
op
9eb763ab87 cwm: fix a semi-transparency border issue with some applications
When running with a compositor the border of some applications (firefox,
chromium, zathura...) is not rendered correctly.  Initializing the highest
significant bits of the color fixes it.

diff from Julien Blanchard (julien at typed-hole [dot] org); ok okan@
2023-03-22 08:27:36 +00:00
okan
481894147a cvsimport
* refs/heads/master:
  Fix overlapping menu items as reported by kn@ and probably others at some point; with op@ and Walter Alejandro Iglesias helping along the way.  Consistently use font ascent+descent instead of an arbitrary font height+1 for individual menu item rectangles and placement.
2022-10-15 16:06:07 +00:00
okan
4a6128d5e4 Fix overlapping menu items as reported by kn@ and probably others at
some point; with op@ and Walter Alejandro Iglesias helping along the
way.  Consistently use font ascent+descent instead of an arbitrary font
height+1 for individual menu item rectangles and placement.

ok kn@ op@
2022-10-15 16:06:07 +00:00
Leah Neukirchen
c55191fdc5 README: update 2022-04-30 17:11:23 +02:00
okan
4e73ce533c cycling fix: when no client is active, warp pointer to last active;
from Walter Alejandro Iglesias.
2022-02-27 14:59:55 +00:00
okan
7af3a7b8b6 cvsimport
* refs/heads/master:
  cycling fix: when no client is active, warp pointer to last active; from Walter Alejandro Iglesias.
  whitespace
  Fix spelling of some unused MWM hints; from Sean C. Farley.
  Add group-last command that shows only the previously active group; ok okan
  Allow bare numbers for key and mouse bindings; taken from similar support in other parse.y's; from Leon Fischer <lfischer@airmail.cc>.
  sync parse.y changes from base; ok naddy@
  Do not attempt to grab keys without a keycode; this incidentally allows XF86 keys support.
2022-02-27 14:59:55 +00:00
okan
496bcc879d whitespace 2022-02-26 15:19:18 +00:00
okan
5e5221d82d Fix spelling of some unused MWM hints; from Sean C. Farley.
While here, flesh out the rest of the MWM hints.
2022-02-26 15:03:42 +00:00
op
7c22b36a23 Add group-last command that shows only the previously active group; ok okan 2022-01-27 18:45:10 +00:00
okan
81a08ddb89 Allow bare numbers for key and mouse bindings; taken from similar
support in other parse.y's; from Leon Fischer <lfischer@airmail.cc>.
2021-12-24 16:00:47 +00:00
Leah Neukirchen
35b0da9202 Makefile: use implicit rule for yacc
Closes #15.
2021-11-30 16:43:23 +01:00
okan
a9eeb04606 sync parse.y changes from base; ok naddy@
original from naddy@:
> Don't declare variables as "unsigned char *" that are passed to
> functions that take "char *" arguments.  Where such chars are
> assigned to int or passed to ctype functions, explicitly cast them
> to unsigned char.
>
> For OpenBSD's clang, -Wpointer-sign has been disabled by default,
> but when the parse.y code was built elsewhere, the compiler would
> complain.
>
> With help from millert@
> ok benno@ deraadt@
2021-11-22 00:51:54 +00:00
okan
055b84f4d4 Do not attempt to grab keys without a keycode; this incidentally allows
XF86 keys support.

found and fix by Luis Henriques <henrix@camandro.org>
2021-11-19 19:13:14 +00:00
Leah Neukirchen
ce65ff30c7 README: update IRC channel 2021-05-21 10:12:43 +02:00
kn
d46f34f01e Keep pointer within window on maximize/fullscreen toggle
Spawn a window, maximize it in any way, move the cursor to a window border
that is not on the screen's edge and unmaximize again:  While the window
goes back the cursor stays at the screen's edge, i.e.  focus is lost to the
underlaying window.

Moving, resizing, tiling or snapping windows in any way always moves the
cursor along iff needed, e.g. using MS-[hjkl] to move a small window from
the center to the edge keeps the cursor within window borders -- no matter
what you do with the keyboard, focus stays on that window.

Make CM-f, CM-m, CM-equal and CMS-equal (default bindings) for toggling
full-screen mode, maximization, vertical maximization and horizontal
maximization of the current window drag the cursor along if needed as well.

OK okan kmos dv
2021-04-22 10:02:55 +00:00
kn
f24dd47517 cvsimport
* refs/heads/master:
  Keep pointer within window on maximize/fullscreen toggle
2021-04-22 10:02:55 +00:00
12 changed files with 129 additions and 65 deletions

View File

@ -11,7 +11,7 @@ SRCS= calmwm.c screen.c xmalloc.c client.c menu.c \
OBJS= calmwm.o screen.o xmalloc.o client.o menu.o \
search.o util.o xutil.o conf.o xevents.o group.o \
kbfunc.o strlcpy.o strlcat.o y.tab.o \
kbfunc.o strlcpy.o strlcat.o parse.o \
strtonum.o reallocarray.o
PKG_CONFIG?= pkg-config
@ -27,12 +27,9 @@ MANPREFIX?= ${PREFIX}/share/man
all: ${PROG}
clean:
rm -f ${OBJS} ${PROG} y.tab.c
rm -f ${OBJS} ${PROG} parse.c
y.tab.c: parse.y
yacc parse.y
${PROG}: ${OBJS} y.tab.o
${PROG}: ${OBJS}
${CC} ${OBJS} ${LDFLAGS} -o ${PROG}
.c.o:
@ -53,3 +50,5 @@ sign:
gpg2 --armor --detach-sign cwm-$$VERSION.tar.gz && \
signify -S -s ~/.signify/cwm.sec -m cwm-$$VERSION.tar.gz && \
sed -i '1cuntrusted comment: verify with cwm.pub' cwm-$$VERSION.tar.gz.sig
.PRECIOUS: parse.c

14
README
View File

@ -15,7 +15,8 @@ Releases are roughly coordinated.
The revision controlled version is at https://github.com/leahneukirchen/cwm
Releases can be found at http://leahneukirchen.org/releases
You are welcome to join the IRC channel ##cwm on Freenode to talk about cwm.
You are welcome to join the IRC channel ##cwm on irc.libera.chat
to talk about cwm.
ChangeLog:
@ -129,6 +130,17 @@ Changes made between OpenBSD 6.6 and 6.7
* Allowed use of window-htile and window-vtile with the "empty" group
clients in cwm(1).
2022-04-30: Eighth public release 7.1 of portable cwm.
Changes made between OpenBSD 6.9 and 7.0
* Changed cwm(1) maximization and full-screen mode toggling to keep
the cursor within the window, preventing focus loss.
Changes made between OpenBSD 7.0 and 7.1
* Added a cwm(1) "group-last" command that shows only the previously
active group.
* Allowed bare numbers for key and mouse bindings in cwm(1).
--Leah Neukirchen <leah@vuxu.org>

View File

@ -235,6 +235,7 @@ struct screen_ctx {
struct region_q regionq;
struct group_q groupq;
struct group_ctx *group_active;
struct group_ctx *group_last;
Colormap colormap;
Visual *visual;
struct {
@ -329,30 +330,39 @@ struct conf {
/* MWM hints */
struct mwm_hints {
#define MWM_HINTS_ELEMENTS 3L
#define MWM_FLAGS_STATUS (1<<3)
#define MWM_HINTS_ELEMENTS 5L
#define MWM_FLAGS_FUNCTIONS (1<<0)
#define MWM_FLAGS_DECORATIONS (1<<1)
#define MWM_FLAGS_INPUT_MODE (1<<2)
#define MWM_HINTS_FUNCTIONS (1L << 0)
#define MWM_HINTS_DECORATIONS (1L << 1)
#define MWM_HINTS_INPUT_MODE (1L << 2)
#define MWM_HINTS_STATUS (1L << 3)
unsigned long flags;
#define MWM_FUNCS_ALL (1<<0)
#define MWM_FUNCS_RESIZE (1<<1)
#define MWM_FUNCS_MOVE (1<<2)
#define MWM_FUNCS_MINIMIZE (1<<3)
#define MWM_FUNCS_MAXIMIZE (1<<4)
#define MWM_FUNCS_CLOSE (1<<5)
#define MWM_FUNC_ALL (1L << 0)
#define MWM_FUNC_RESIZE (1L << 1)
#define MWM_FUNC_MOVE (1L << 2)
#define MWM_FUNC_MINIMIZE (1L << 3)
#define MWM_FUNC_MAXIMIZE (1L << 4)
#define MWM_FUNC_CLOSE (1L << 5)
unsigned long functions;
#define MWM_DECOR_ALL (1<<0)
#define MWM_DECOR_BORDER (1<<1)
#define MWM_DECOR_RESIZE_HANDLE (1<<2)
#define MWM_DECOR_TITLEBAR (1<<3)
#define MWM_DECOR_MENU (1<<4)
#define MWM_DECOR_MINIMIZE (1<<5)
#define MWM_DECOR_MAXIMIZE (1<<6)
#define MWM_DECOR_ALL (1L << 0)
#define MWM_DECOR_BORDER (1L << 1)
#define MWM_DECOR_RESIZEH (1L << 2)
#define MWM_DECOR_TITLE (1L << 3)
#define MWM_DECOR_MENU (1L << 4)
#define MWM_DECOR_MINIMIZE (1L << 5)
#define MWM_DECOR_MAXIMIZE (1L << 6)
unsigned long decorations;
#define MWM_INPUT_MODELESS 0
#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
#define MWM_INPUT_SYSTEM_MODAL 2
#define MWM_INPUT_FULL_APPLICATION_MODAL 3
long inputMode;
#define MWM_TEAROFF_WINDOW (1L << 0)
unsigned long status;
};
enum cwmh {
@ -524,6 +534,7 @@ void kbfunc_client_toggle_group(void *, struct cargs *);
void kbfunc_client_movetogroup(void *, struct cargs *);
void kbfunc_group_toggle(void *, struct cargs *);
void kbfunc_group_only(void *, struct cargs *);
void kbfunc_group_last(void *, struct cargs *);
void kbfunc_group_close(void *, struct cargs *);
void kbfunc_group_cycle(void *, struct cargs *);
void kbfunc_group_toggle_all(void *, struct cargs *);
@ -597,7 +608,7 @@ int xu_ewmh_get_net_wm_desktop(struct client_ctx *, long *);
void xu_ewmh_set_net_wm_desktop(struct client_ctx *);
Atom *xu_ewmh_get_net_wm_state(struct client_ctx *, int *);
void xu_ewmh_handle_net_wm_state_msg(struct client_ctx *,
int, Atom , Atom);
int, Atom, Atom);
void xu_ewmh_set_net_wm_state(struct client_ctx *);
void xu_ewmh_restore_net_wm_state(struct client_ctx *);

View File

@ -336,6 +336,7 @@ client_toggle_fullscreen(struct client_ctx *cc)
resize:
client_resize(cc, 0);
xu_ewmh_set_net_wm_state(cc);
client_ptr_inbound(cc, 1);
}
void
@ -376,6 +377,7 @@ client_toggle_maximize(struct client_ctx *cc)
resize:
client_resize(cc, 0);
xu_ewmh_set_net_wm_state(cc);
client_ptr_inbound(cc, 1);
}
void
@ -408,6 +410,7 @@ client_toggle_vmaximize(struct client_ctx *cc)
resize:
client_resize(cc, 0);
xu_ewmh_set_net_wm_state(cc);
client_ptr_inbound(cc, 1);
}
void
@ -440,6 +443,7 @@ client_toggle_hmaximize(struct client_ctx *cc)
resize:
client_resize(cc, 0);
xu_ewmh_set_net_wm_state(cc);
client_ptr_inbound(cc, 1);
}
void
@ -592,7 +596,7 @@ client_draw_border(struct client_ctx *cc)
pixel = sc->xftcolor[CWM_COLOR_BORDER_URGENCY].pixel;
XSetWindowBorderWidth(X_Dpy, cc->win, (unsigned int)cc->bwidth);
XSetWindowBorder(X_Dpy, cc->win, pixel);
XSetWindowBorder(X_Dpy, cc->win, pixel | (0xffu << 24));
}
static void
@ -845,13 +849,15 @@ client_mwm_hints(struct client_ctx *cc)
if (xu_get_prop(cc->win, cwmh[_MOTIF_WM_HINTS],
cwmh[_MOTIF_WM_HINTS], MWM_HINTS_ELEMENTS,
(unsigned char **)&mwmh) == MWM_HINTS_ELEMENTS) {
if (mwmh->flags & MWM_FLAGS_DECORATIONS &&
!(mwmh->decorations & MWM_DECOR_ALL) &&
!(mwmh->decorations & MWM_DECOR_BORDER))
(unsigned char **)&mwmh) <= 0)
return;
if ((mwmh->flags & MWM_HINTS_DECORATIONS) &&
!(mwmh->decorations & MWM_DECOR_ALL)) {
if (!(mwmh->decorations & MWM_DECOR_BORDER))
cc->bwidth = 0;
XFree(mwmh);
}
XFree(mwmh);
}
void

3
conf.c
View File

@ -139,6 +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-last, group_last, 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) },
@ -669,6 +670,8 @@ conf_grab_kbd(Window win)
TAILQ_FOREACH(kb, &Conf.keybindq, entry) {
kc = XKeysymToKeycode(X_Dpy, kb->press.keysym);
if (kc == 0)
continue;
if ((XkbKeycodeToKeysym(X_Dpy, kc, 0, 0) != kb->press.keysym) &&
(XkbKeycodeToKeysym(X_Dpy, kc, 0, 1) == kb->press.keysym))
kb->modmask |= ShiftMask;

View File

@ -273,6 +273,8 @@ menu.
Toggle visibility of group n, where n is 1-9.
.It group-only-[n]
Show only group n, where n is 1-9, hiding other groups.
.It group-last
Show only the previously active group.
.It group-close-[n]
Close all windows in group n, where n is 1-9.
.It group-toggle-all

View File

@ -215,6 +215,9 @@ group_only(struct screen_ctx *sc, int idx)
{
struct group_ctx *gc;
if (sc->group_last != sc->group_active)
sc->group_last = sc->group_active;
TAILQ_FOREACH(gc, &sc->groupq, entry) {
if (gc->num == idx)
group_show(gc);

View File

@ -453,7 +453,16 @@ kbfunc_client_cycle(void *ctx, struct cargs *cargs)
newcc->ptr.x = newcc->geom.w / 2;
newcc->ptr.y = newcc->geom.h / 2;
}
client_ptr_warp(newcc);
/* When no client is active, warp pointer to last active. */
if (oldcc->flags & (CLIENT_ACTIVE))
client_ptr_warp(newcc);
else if (oldcc->flags & (CLIENT_SKIP_CYCLE))
client_ptr_warp(newcc);
else {
client_raise(oldcc);
client_ptr_warp(oldcc);
}
}
void
@ -481,6 +490,14 @@ kbfunc_group_only(void *ctx, struct cargs *cargs)
group_only(ctx, cargs->flag);
}
void
kbfunc_group_last(void *ctx, struct cargs *cargs)
{
struct screen_ctx *sc = ctx;
group_only(ctx, sc->group_last->num);
}
void
kbfunc_group_toggle(void *ctx, struct cargs *cargs)
{

25
menu.c
View File

@ -355,7 +355,7 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
XftTextExtentsUtf8(X_Dpy, sc->xftfont,
(const FcChar8*)mc->dispstr, strlen(mc->dispstr), &extents);
mc->geom.w = extents.xOff;
mc->geom.h = sc->xftfont->height + 1;
mc->geom.h = sc->xftfont->ascent + sc->xftfont->descent;
mc->num = 1;
TAILQ_FOREACH(mi, resultq, resultentry) {
@ -364,7 +364,7 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
(const FcChar8*)mi->print,
MIN(strlen(mi->print), MENU_MAXENTRY), &extents);
mc->geom.w = MAX(mc->geom.w, extents.xOff);
mc->geom.h += sc->xftfont->height + 1;
mc->geom.h += sc->xftfont->ascent + sc->xftfont->descent;
mc->num++;
}
@ -403,15 +403,15 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
(const FcChar8*)mc->dispstr, strlen(mc->dispstr));
TAILQ_FOREACH(mi, resultq, resultentry) {
int y = n * (sc->xftfont->height + 1) + sc->xftfont->ascent + 1;
int y = n * (sc->xftfont->ascent + sc->xftfont->descent);
/* Stop drawing when menu doesn't fit inside the screen. */
if (mc->geom.y + y > area.h)
if (mc->geom.y + y >= area.h)
break;
XftDrawStringUtf8(mc->xftdraw,
&sc->xftcolor[CWM_COLOR_MENU_FONT], sc->xftfont,
0, y,
0, y + sc->xftfont->ascent,
(const FcChar8*)mi->print, strlen(mi->print));
n++;
}
@ -425,7 +425,7 @@ menu_draw_entry(struct menu_ctx *mc, struct menu_q *resultq,
{
struct screen_ctx *sc = mc->sc;
struct menu *mi;
int color, i = 1;
int color, i = 1, y;
TAILQ_FOREACH(mi, resultq, resultentry)
if (entry == i++)
@ -433,14 +433,13 @@ menu_draw_entry(struct menu_ctx *mc, struct menu_q *resultq,
if (mi == NULL)
return;
y = entry * (sc->xftfont->ascent + sc->xftfont->descent);
color = (active) ? CWM_COLOR_MENU_FG : CWM_COLOR_MENU_BG;
XftDrawRect(mc->xftdraw, &sc->xftcolor[color], 0,
(sc->xftfont->height + 1) * entry, mc->geom.w,
(sc->xftfont->height + 1) + sc->xftfont->descent);
XftDrawRect(mc->xftdraw, &sc->xftcolor[color], 0, y,
mc->geom.w, sc->xftfont->ascent + sc->xftfont->descent);
color = (active) ? CWM_COLOR_MENU_FONT_SEL : CWM_COLOR_MENU_FONT;
XftDrawStringUtf8(mc->xftdraw,
&sc->xftcolor[color], sc->xftfont,
0, (sc->xftfont->height + 1) * entry + sc->xftfont->ascent + 1,
&sc->xftcolor[color], sc->xftfont, 0, y + sc->xftfont->ascent,
(const FcChar8*)mi->print, strlen(mi->print));
}
@ -487,11 +486,11 @@ menu_calc_entry(struct menu_ctx *mc, int x, int y)
struct screen_ctx *sc = mc->sc;
int entry;
entry = y / (sc->xftfont->height + 1);
entry = y / (sc->xftfont->ascent + sc->xftfont->descent);
/* in bounds? */
if (x < 0 || x > mc->geom.w || y < 0 ||
y > (sc->xftfont->height + 1) * mc->num ||
y > (sc->xftfont->ascent + sc->xftfont->descent) * mc->num ||
entry < 0 || entry >= mc->num)
entry = -1;

41
parse.y
View File

@ -83,7 +83,7 @@ typedef struct {
%token <v.string> STRING
%token <v.number> NUMBER
%type <v.number> yesno
%type <v.string> string
%type <v.string> string numberstring
%%
grammar : /* empty */
@ -106,6 +106,17 @@ string : string STRING {
| STRING
;
numberstring : NUMBER {
char *s;
if (asprintf(&s, "%lld", $1) == -1) {
yyerror("string: asprintf");
YYERROR;
}
$$ = s;
}
| STRING
;
yesno : YES { $$ = 1; }
| NO { $$ = 0; }
;
@ -211,7 +222,7 @@ main : FONTNAME STRING {
conf->gap.left = $4;
conf->gap.right = $5;
}
| BINDKEY STRING string {
| BINDKEY numberstring string {
if (!conf_bind_key(conf, $2, $3)) {
yyerror("invalid bind-key: %s %s", $2, $3);
free($2);
@ -221,7 +232,7 @@ main : FONTNAME STRING {
free($2);
free($3);
}
| UNBINDKEY STRING {
| UNBINDKEY numberstring {
if (!conf_bind_key(conf, $2, NULL)) {
yyerror("invalid unbind-key: %s", $2);
free($2);
@ -229,7 +240,7 @@ main : FONTNAME STRING {
}
free($2);
}
| BINDMOUSE STRING string {
| BINDMOUSE numberstring string {
if (!conf_bind_mouse(conf, $2, $3)) {
yyerror("invalid bind-mouse: %s %s", $2, $3);
free($2);
@ -239,7 +250,7 @@ main : FONTNAME STRING {
free($2);
free($3);
}
| UNBINDMOUSE STRING {
| UNBINDMOUSE numberstring {
if (!conf_bind_mouse(conf, $2, NULL)) {
yyerror("invalid unbind-mouse: %s", $2);
free($2);
@ -376,7 +387,7 @@ lgetc(int quotec)
if (parsebuf) {
/* Read character from the parsebuffer instead of input. */
if (parseindex >= 0) {
c = parsebuf[parseindex++];
c = (unsigned char)parsebuf[parseindex++];
if (c != '\0')
return (c);
parsebuf = NULL;
@ -385,7 +396,7 @@ lgetc(int quotec)
}
if (pushback_index)
return (pushback_buffer[--pushback_index]);
return ((unsigned char)pushback_buffer[--pushback_index]);
if (quotec) {
if ((c = getc(file->stream)) == EOF) {
@ -426,10 +437,10 @@ lungetc(int c)
if (parseindex >= 0)
return (c);
}
if (pushback_index < MAXPUSHBACK-1)
return (pushback_buffer[pushback_index++] = c);
else
if (pushback_index + 1 >= MAXPUSHBACK)
return (EOF);
pushback_buffer[pushback_index++] = c;
return (c);
}
int
@ -442,7 +453,7 @@ findeol(void)
/* skip to either EOF or the first real EOL */
while (1) {
if (pushback_index)
c = pushback_buffer[--pushback_index];
c = (unsigned char)pushback_buffer[--pushback_index];
else
c = lgetc(0);
if (c == '\n') {
@ -516,7 +527,7 @@ yylex(void)
if (c == '-' || isdigit(c)) {
do {
*p++ = c;
if ((unsigned)(p-buf) >= sizeof(buf)) {
if ((size_t)(p-buf) >= sizeof(buf)) {
yyerror("string too long");
return (findeol());
}
@ -539,8 +550,8 @@ yylex(void)
} else {
nodigits:
while (p > buf + 1)
lungetc(*--p);
c = *--p;
lungetc((unsigned char)*--p);
c = (unsigned char)*--p;
if (c == '-')
return (c);
}
@ -555,7 +566,7 @@ nodigits:
if (isalnum(c) || c == ':' || c == '_' || c == '*' || c == '/') {
do {
*p++ = c;
if ((unsigned)(p-buf) >= sizeof(buf)) {
if ((size_t)(p-buf) >= sizeof(buf)) {
yyerror("string too long");
return (findeol());
}

View File

@ -60,6 +60,7 @@ screen_init(int which)
xu_ewmh_net_supported_wm_check(sc);
conf_group(sc);
sc->group_last = sc->group_active;
screen_update_geometry(sc);
xu_ewmh_net_desktop_names(sc);