You are not logged in.
The bstack patch, adds important declarations to config.def.h during patching, and you also need to add some keys yourself and such. I dunno about the statuscolor one, as I don't use it...
So, if you have allready a predefined config.h, with those declarations/keys etc. set, then you can just copy it over without renaming it, and it dosen't matter if it's before or after the patching...
Right. I already have the keys and such in my existing config.h and you would have to add that but I guess I was assuming anyone using bstack probably already knows that. I was just thinking how it could be done without an existing config.h. (someone starting from scratch). Nothing else is needed for the statuscolors patch.
I don't bother installing dwm, myself...
I just go to ~/.builds/dwm where I have the dwm tarball, patches, config.h and a setup-script which builds dwm and copy the binary over to ~/.bin.
Then to make changes, I just edit config.h and/or comment-out or un-comment the list of patches to apply in the setup script, and then I run the srcipt to reinstall...
Yeah, I've noticed a lot of people seem to do it that way, but I was trying to figure out how to do it with a PKGBUILD. Anyway, after adding my changes to the config.h (I made a patch and added it to the PKGBUILD - of course this would also require an existing config.h ; or you could edit it by hand at this point without an existing config.h and then rebuild it), I can confirm that it works with both patches. I'm using it right now. It's exactly like I had before.
Sorry for all the incoherent rambling, I'm just trying to sort it all out in my old brain with limited knowledge and figure out the easiest way for me to do it.
Offline
Right. I already have the keys and such in my existing config.h and you would have to add that but I guess I was assuming anyone using bstack probably already knows that.
Obviously, but as you yourself stated that it didn't work with copying over config.h, but only copying over as config.def.h, then I could conclude that you're missing something, unless you're doing it wrong...
I was just thinking how it could be done without an existing config.h. (someone starting from scratch). Nothing else is needed for the statuscolors patch.
Well, then you would need to add an extra patch which adds the missing stuff to config.def.h, but as you yourself write later in your post, then you allready reached that conclusion yourself
Last edited by mhertz (2011-10-15 22:00:29)
Offline
Obviously, but as you yourself stated that it didn't work with copying over config.h, but only copying over as config.def.h, then I could conclude that you're missing something, unless you're doing it wrong...
Maybe that's because
cp $srcdir/config.h config.def.h
seems to be unnessasary. I removed that line in the PKGBUILD and it does work. But I guess the first example I gave would be the way to go if you have an existing config.h. ( I think I stole that from Meyithi BTW and changed it a little) Again, forgive my ignorance. I'm still kinda lost with PKGBUILD's, obviously. I think I have a little better understanding of it now though?
Anyway, I decided to try to build dwm from source and see how it went. I probably should have done that before. It's very simple and straightforward. Maybe I'll just do that from now on. Can i see your script that you mentioned before?
@thanks for everything mhertz
edit: Actually I think I will do it from source from now on. I just copied the binary into ~/bin as you suggested, and changed the last line of my .xinitrc to exec ~/bin/dwm.
edit again: Obviously, I don't need to change it to exec ~/bin/dwm since /bin is already in my path. I still had dwm installed from before and just realized it when I uninstalled it. Just ignore me when I say something stupid.
Last edited by stlarch (2011-10-17 05:38:07)
Offline
http://ompldr.org/tYWlxYg
Coded a OpenBox styled menu for dwm.static const menuCtx gameMenu[] = { { "Touhou >", &touhouMenu[0], NULL, {0} }, { "-------------", NULL, NULL, {0} }, { "Last Remnant ", NULL, spawn, pikakuvake("/home/jari/.wine/drive_c/Program Files/The Last Remnant/Binaries/TLR.exe") }, MENUEND, }; static const menuCtx rootMenu[] = { { "Internet >", &internetMenu[0], NULL, {0} }, { "Games >", &gameMenu[0], NULL, {0} }, MENUEND, };
My dwm sources are in github, it should not take too much modifications to include it in vanilla dwm.
This menu is very cool man!
How to add this in my dwm?
I added this lines to my dwm.c
typedef struct menuCtx {
char *title;
const struct menuCtx *ctx;
void (*func)(const Arg *);
const Arg arg;
} menuCtx;
typedef struct menu_t {
Window win;
int x, y, w, h;
Drawable drawable;
struct menu_t *next, *child;
const struct menuCtx *ctx, *sel;
} menu_t;
menu_t *menu = NULL;
/* function declarations */
static void togglemenu(const Arg *arg);
and this lines 570- 803 from your dwm.c
I modified my config.h
added this
/* menus */
#define MENUEND { NULL, NULL, NULL, {0} }
#define MENUSEP(x) { x, NULL, NULL, {0} }
static const menuCtx touhouMenu[] = {
{ "TH06 Embodiment of Scarlet Devil ", NULL, spawn, THCMD("TH06/th06e.exe") },
{ "TH07 Perfect Cherry Blossom ", NULL, spawn, THCMD("TH07/th07e.exe") },
{ "TH07.5 Immaterial and Missing Power", NULL, spawn, THCMD("TH07.5/th075e.exe") },
{ "TH08 Imperishable Night ", NULL, spawn, THCMD("TH08/th08.exe") },
{ "TH09 Phantasmagoria of Flower View ", NULL, spawn, THCMD("TH09/th09e.exe") },
{ "TH09.5 Shoot the Bullet ", NULL, spawn, THCMD("TH09.5/th095.exe") },
{ "TH10 Mountain of Faith ", NULL, spawn, THCMD("TH10/th10e.exe") },
{ "TH10.5 Scarlet Weather Rhapsody ", NULL, spawn, THCMD("TH10.5/th105e.exe") },
{ "TH11 Subterranean Animism ", NULL, spawn, THCMD("TH11/th11e.exe") },
{ "TH12 Undefined Fantastic Object ", NULL, spawn, THCMD("TH12/th12e.exe") },
{ "TH12.3 Touhou Hisoutensoku ", NULL, spawn, THCMD("TH12.3/th123e.exe") },
{ "TH12.5 Double Spoiler ", NULL, spawn, THCMD("TH12.5/th125e.exe") },
{ "TH12.8 Fairy Wars ", NULL, spawn, THCMD("TH12.8/th128e.exe") },
{ "TH13 Ten Desires ", NULL, spawn, THCMD("TH13/th13.exe") },
MENUSEP("-----------------------------------"),
{ "Doujin +", NULL, spawn, FM(THDIR"/Doujin") },
MENUEND,
};
static const menuCtx internetMenu[] = {
{ "Opera ", NULL, spawn, {.v = opera } },
MENUSEP("--------"),
{ "rTorrent", NULL, spawn, {.v = torrent } },
MENUSEP("--------"),
{ "IRC ", NULL, spawn, {.v = irc } },
{ "MSN ", NULL, spawn, {.v = msn } },
MENUSEP("--------"),
{ "RSS ", NULL, spawn, {.v = rss } },
MENUEND,
};
static const menuCtx gameMenu[] = {
{ "Touhou >", &touhouMenu[0], NULL, {0} },
{ "Eroge +", NULL, spawn,
FM("/media/Storage/Bishoujo Pelit") },
MENUSEP("-----------------------"),
{ "Cave Story ", NULL, spawn,
pikakuvake(GAMES"/CaveStory/doukutsu") },
{ "Last Remnant ", NULL, spawn,
pikakuvake(HOME"/.wine/drive_c/Program Files/The Last Remnant/Binaries/TLR.exe") },
{ "ALLTYNEX Second ", NULL, spawn,
pikakuvake(GAMES"/ALLTYNEX Second/alltynex2nd.exe") },
{ "RefRain ", NULL, spawn,
pikakuvake(GAMES"/RefRain/runGame.sh") },
{ "Edens Aegis ", NULL, spawn,
pikakuvake(GAMES"/Edens Aegis/EdensAegis.run") },
MENUSEP("-----------------------"),
{ "Grand Fantasia ", NULL, spawn,
pikakuvake(HOME"/.wine/drive_c/AeriaGames/GrandFantasia/runGame.sh") },
{ "Spiral Knights ", NULL, spawn,
pikakuvake(HOME"/spiral/spiral") },
MENUSEP("-----------------------"),
{ "Ys The Ark of Napishtim", NULL, spawn,
pikakuvake(GAMES"/Ys The Ark of Napishtim/ys6_win_dx9.exe") },
{ "Ys The Oath in Felghana", NULL, spawn,
pikakuvake(GAMES"/Ys The Oath in Felghana/ysf_win_dx9.exe") },
{ "Ys Origins ", NULL, spawn,
pikakuvake(GAMES"/Ys Origins/YSO_WIN.exe") },
MENUSEP("-----------------------"),
{ "Sora no Kiseki ", NULL, spawn,
pikakuvake(GAMES"/Eiyuu Densetsu - Sora no Kiseki/ED6_WIN.run") },
{ "Sora no Kiseki SC ", NULL, spawn,
pikakuvake(GAMES"/Eiyuu Densetsu - Sora no Kiseki SC/ED6_WIN2.run") },
{ "Sora no Kiseki TC ", NULL, spawn,
pikakuvake(GAMES"/Eiyuu Densetsu - Sora no Kiseki TC/ED6_WIN3.run") },
MENUSEP("-----------------------"),
{ "MAME ", NULL, spawn, {.v = mame } },
{ "NO$GBA ", NULL, spawn,
pikakuvake(EMUS"/NoGBA/NO$GBA.exe") },
{ "VBA-M ", NULL, spawn, {.v = gvbam } },
MENUSEP("-----------------------"),
{ "Steam ", NULL, spawn,
pikakuvake(HOME"/.wine/drive_c/Program Files/Steam/Steam.exe") },
MENUEND,
};
static const menuCtx archMenu[] = {
{ "Nitrogen", NULL, spawn, {.v = nitrogen} },
MENUSEP("--------"),
{ "Exit ", NULL, spawn, {.v = oblogout} },
MENUEND,
};
static const menuCtx rootMenu[] = {
{ "Music ", NULL, spawn, {.v = deadbeef } },
{ "Manga ", NULL, spawn, {.v = comix } },
MENUSEP("-------------"),
{ "Internet >", &internetMenu[0], NULL, {0} },
{ "Games >", &gameMenu[0], NULL, {0} },
MENUSEP("-------------"),
{ "ArchLinux >", &archMenu[0], NULL, {0} },
MENUEND,
};
but it still fails works.
Thanks.
Last edited by ivoarch (2011-10-16 17:15:59)
Offline
Can i see your script that you mentioned before?
Sure you can, but it's nothing special though...
I have two scripts, one for stable dwm, currently v5.9, and one for latest hg tip, but unfortunetly JokerBoy's pertag2 patch fails upon 3 chunks with that currently, so beware that only the "stable" script works now, but i'll post both scripts nonetheless...
Also, you need mercurial installed, and the "stable" script needs to get it's $ver variable updated upon each new stable dwm update, but it's updated correctly now for v5.9, and finally, remember that I use ~/.bin and not ~/bin...
"Stable":
#!/bin/bash
ver=5.9
[ -d dwm-$ver ] && rm -r dwm-$ver
curl http://dl.suckless.org/dwm/dwm-$ver.tar.gz 2>/dev/null | tar xz
[ -d dwm ] && rm -r dwm
hg clone https://bitbucket.org/jokerboy/dwm 2>/dev/null
cp config.h dwm-$ver
cd dwm-$ver
patch < ../dwm/*-pertag2.diff
patch < ../dwm/*-push.diff
patch < ../dwm/*-cycle.diff
patch < ../dwm/*-gaplessgrid.diff
patch < ../dwm/*-monocle_count.diff
patch < ../dwm/*-monocle_no_borders.diff
patch < ../dwm/*-focusonclick.diff
patch < ../dwm/*-viewontag.diff
make
cp dwm ~/.bin
hg tip:
#!/bin/bash
[ -d dwm ] && rm -r dwm
hg clone http://hg.suckless.org/dwm
[ -d patches ] && rm -r patches
hg clone https://bitbucket.org/jokerboy/dwm patches 2>/dev/null
cp config.h dwm
cd dwm
patch < ../patches/*-pertag2.diff
patch < ../patches/*-push.diff
patch < ../patches/*-cycle.diff
patch < ../patches/*-gaplessgrid.diff
patch < ../patches/*-monocle_count.diff
patch < ../patches/*-monocle_no_borders.diff
patch < ../patches/*-focusonclick.diff
patch < ../patches/*-viewontag.diff
make
cp dwm ~/.bin
Last edited by mhertz (2011-10-16 23:46:54)
Offline
This menu is very cool man!
How to add this in my dwm?
I added this lines to my dwm.c*snip*
but it still fails works.
Thanks.
You need more than that, also my config prob won't work.
First add these to above the function declarations in dwm.c
typedef struct menuCtx {
char *title;
const struct menuCtx *ctx;
void (*func)(const Arg *);
const Arg arg;
} menuCtx;
typedef struct menu_t {
Window win;
int x, y, w, h;
Drawable drawable;
struct menu_t *next, *child;
const struct menuCtx *ctx, *sel;
} menu_t;
menu_t *menu = NULL;
Then add this to the function declarations
static void togglemenu(const Arg *arg);
static void motionnotify(XEvent *e);
Then put, these somewhere in dwm.c as long as they are above the buttonpress function
static menu_t* openmenupos( const menuCtx *ctx, int x, int y );
static void closemenu( menu_t *target );
static void
updatemenu( menu_t *m, int x, int y ) {
Drawable dble = dc.drawable;
int ow = dc.w, oh = dc.h, ox = dc.x, oy = dc.y;
int sely = 0;
size_t col;
if(!m) return;
const menuCtx *osel = m->sel;
m->sel = NULL;
dc.drawable = m->drawable;
#ifdef XFT
XftDrawChange(dc.xftdrawable, dc.drawable);
#endif
size_t i;
dc.x = 0; dc.y = 0;
dc.w = m->w; dc.h = m->h;
for(i = 0; m->ctx[i].title; ++i)
{
col = x > 0 && x < TEXTW2(m->ctx[i].title)
&& y > dc.y && y < dc.y + dc.font.height ? 5 : 6;
drawtext(m->ctx[i].title, col, False);
if(col == 5) { m->sel = &m->ctx[i]; sely = dc.y; }
dc.y += dc.font.height;
}
XCopyArea(dpy, dc.drawable, m->win, dc.gc, 0, 0, m->w, m->h, 0, 0);
XSync(dpy, False);
dc.w = ow; dc.h = oh; dc.x = ox; dc.y = oy;
dc.drawable = dble;
#ifdef XFT
XftDrawChange(dc.xftdrawable, dc.drawable);
#endif
if(m->sel && m->sel != osel)
{
if(m->child) { closemenu(m->child); m->child = NULL; }
if(m->sel->ctx != NULL)
m->child = openmenupos( m->sel->ctx, m->x + m->w, m->y + sely );
}
}
menu_t*
wintomenu( Window win )
{
menu_t *m;
if(!menu) return(NULL);
for( m = menu; m; m = m->next )
if(m->win == win) return(m);
return(NULL);
}
menu_t*
ctxtomenu( const menuCtx *ctx )
{
menu_t *m;
if(!menu) return(NULL);
for( m = menu; m; m = m->next )
if(m->ctx == ctx) return(m);
return(NULL);
}
static int
createmenu( menu_t *m, const menuCtx *ctx, int x, int y ) {
size_t i;
if(ctxtomenu(ctx)) return(-1);
m->x = x;
m->y = y;
m->w = 0;
m->h = 0;
m->ctx = ctx;
m->sel = NULL;
m->child= NULL;
for(i = 0; m->ctx[i].title; ++i)
{
if(m->w < TEXTW2(m->ctx[i].title))
m->w = TEXTW2(m->ctx[i].title);
m->h += dc.font.height;
}
if(i == 0) return(-1);
XSetWindowAttributes wattr;
wattr.override_redirect = True;
wattr.background_pixmap = ParentRelative;
wattr.event_mask = ButtonPressMask|ExposureMask;
m->win = XCreateWindow(dpy, root, m->x, m->y, m->w, m->h, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWBackPixmap|CWOverrideRedirect|CWEventMask, &wattr);
if(m == menu)
XSelectInput(dpy, m->win, PointerMotionMask|ButtonPressMask);
else
XSelectInput(dpy, m->win, PointerMotionMask|ButtonPressMask|LeaveWindowMask);
XDefineCursor(dpy, m->win, cursor[CurNormal]);
XMapRaised(dpy, m->win);
m->drawable = XCreatePixmap(dpy, root, m->w, m->h, DefaultDepth(dpy, screen));
updatemenu(m, m->x, m->y);
if(selmon && selmon->sel)
{ grabbuttons(selmon->sel,False); XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); XSync(dpy,False); }
return(0);
}
static menu_t*
openmenupos( const menuCtx *ctx, int x, int y ) {
menu_t **m, *mm;
m = &menu;
mm = menu;
for(; mm; mm = mm->next)
m = &mm->next;
*m = calloc(1, sizeof(menu_t));
if(!*m)
return NULL;
(*m)->next = NULL;
if(createmenu(*m, ctx, x, y) == -1)
{ free(*m); *m = NULL; }
return *m;
}
static menu_t*
openmenu( const menuCtx *ctx ) {
int x, y;
getrootptr( &x, &y );
return openmenupos( ctx, x, y );
}
static void
closemenu( menu_t *target )
{
menu_t **m, *mm;
if(!target) return;
/* this is not valid child anymore */
for( mm = menu; mm; mm = mm->next )
if(mm->child == target) mm->child = NULL;
/* close childs */
for( mm = target->child; mm; mm = mm->child )
closemenu( mm );
/* remove */
m = &menu;
for( mm = menu; mm && mm->next && mm->next != target; mm = mm->next )
m = &mm;
(*m)->next = target->next;
XFreePixmap(dpy, target->drawable);
XDestroyWindow(dpy, target->win);
free(target);
XSync(dpy, False);
}
static void
closemenus(void) {
if(!menu) return;
menu_t *m = menu, *next = NULL;
while(m)
{
XDestroyWindow(dpy, m->win);
next = m->next; free(m);
m = next;
}
XSync(dpy, False);
menu = NULL;
}
void
togglemenu(const Arg *arg) {
if(!menu)
openmenu(&rootMenu[0]);
else
closemenus();
}
static void
buttonmenu( menu_t *m, int x, int y )
{
if(!m) return;
updatemenu(m, x, y);
if(!m->sel) return;
if(!m->sel->func) return;
m->sel->func(&m->sel->arg);
closemenus();
}
Then put this into the buttonpress function, below click = ClkRootWin;
(this is optional, it will just close the menu if you press anywhere with left click)
if(ev->button == Button1)
{
if(menu)
if(!(mm = wintomenu(ev->window)))
closemenus();
else
{ buttonmenu(mm, ev->x, ev->y); return; }
}
Ok, now then you'll also need to add a motionnotify event.
(I plan to add keyboard move to the menu later)
add this somewhere in dwm.c
void
motionnotify(XEvent *e) {
menu_t *mm;
XMotionEvent *ev = &e->xmotion;
if( (mm = wintomenu(ev->window)) )
{
updatemenu(mm, ev->x, ev->y);
return;
}
}
And add this below
[EnterNotify] = enternotify,
in dwm.c
[MotionNotify] = motionnotify,
Now, since I use colors index instead of passing reference to the color struct in my dwm-fork(Mainly because I use XFT, and it's more convenient this way anyways), you need to change the updatemenu function a bit.
Change:
size_t col;
To:
unsigned long *col;
Change:
col = x > 0 && x < TEXTW2(m->ctx[i].title)
&& y > dc.y && y < dc.y + dc.font.height ? 5 : 6;
drawtext(m->ctx[i].title, col, False);
if(col == 5) { m->sel = &m->ctx[i]; sely = dc.y; }
To:
col = x > 0 && x < TEXTW2(m->ctx[i].title)
&& y > dc.y && y < dc.y + dc.font.height ? dc.colors[5] : dc.colors[6];
drawtext(m->ctx[i].title, col, False);
if(col == dc.colors[5]) { m->sel = &m->ctx[i]; sely = dc.y; }
And then in your config.h, you can paste this default menu
/* menus */
#define MENUEND { NULL, NULL, NULL, {0} }
#define MENUSEP(x) { x, NULL, NULL, {0} }
/* title, submenu, function, argument */
static const menuCtx rootMenu[] = {
MENUSEP("-------------"),
{ "EMPTY", NULL, NULL, {0} },
MENUSEP("-------------"),
MENUEND,
};
And that should work, maybe.. I have never tested it with vanilla dwm, and mine is quite heavily modified. I haven't tested it without XFT either so.. Good luck I guess.
I might make vanilla dwm patch if there is enough interest.
Offline
Then put this into the buttonpress function, below click = ClkRootWin;
(this is optional, it will just close the menu if you press anywhere with left click)if(ev->button == Button1) { if(menu) if(!(mm = wintomenu(ev->window))) closemenus(); else { buttonmenu(mm, ev->x, ev->y); return; } }
also this
menu_t *mm;
this at the beginning
#define TEXTW2(X) (textnw(X, strlen(X)))
Ok, now then you'll also need to add a motionnotify event.
(I plan to add keyboard move to the menu later)
Great I've been using thingmenu until now and missed that feature
Now, since I use colors index instead of passing reference to the color struct in my dwm-fork(Mainly because I use XFT, and it's more convenient this way anyways), you need to change the updatemenu function a bit.
Change: size_t col; To: unsigned long *col; Change: col = x > 0 && x < TEXTW2(m->ctx[i].title) && y > dc.y && y < dc.y + dc.font.height ? 5 : 6; drawtext(m->ctx[i].title, col, False); if(col == 5) { m->sel = &m->ctx[i]; sely = dc.y; }
Using this it compiles with a few errors
dwm.c: In function ‘updatemenu’:
dwm.c:464:6: warning: assignment makes pointer from integer without a cast [enabled by default]
dwm.c:467:21: warning: comparison between pointer and integer [enabled by default]
dwm crashes when I try to toggle the menu though
To: col = x > 0 && x < TEXTW2(m->ctx[i].title) && y > dc.y && y < dc.y + dc.font.height ? dc.colors[5] : dc.colors[6]; drawtext(m->ctx[i].title, col, False); if(col == dc.colors[5]) { m->sel = &m->ctx[i]; sely = dc.y; }
dwm.c: In function ‘updatemenu’:
dwm.c:460:55: error: ‘DC’ has no member named ‘colors’
dwm.c:460:70: error: ‘DC’ has no member named ‘colors’
dwm.c:462:19: error: ‘DC’ has no member named ‘colors’
That's what I get with this
I don't have any idea about X so it would be nice if you'd know a fix
I tried this with unpatched dwm-5.9
Thanks a lot for making this, hope I can get it to work
Offline
*snip*
That's what I get with this
I don't have any idea about X so it would be nice if you'd know a fixI tried this with unpatched dwm-5.9
Thanks a lot for making this, hope I can get it to work
Thank you for your input, yeah I forgot those couple of parts.. Also I forgot dwm by default does not have multiple color support, so you need to use dc.sel && dc.norm instead.
So:
col = x > 0 && x < TEXTW2(m->ctx[i].title)
&& y > dc.y && y < dc.y + dc.font.height ? dc.sel : dc.norm;
drawtext(m->ctx[i].title, col, False);
if(col == dc.sel) { m->sel = &m->ctx[i]; sely = dc.y; }
While you are it, can you post patch for other people if you are doing this against vanilla dwm-5.9? Would save me some time.
I'll prob do the keyboard part tomorrow
Last edited by Cloudef (2011-10-17 15:56:21)
Offline
Thank you for your input, yeah I forgot those couple of parts.. Also I forgot dwm by default does not have multiple color support, so you need to use dc.sel && dc.norm instead.
So:
col = x > 0 && x < TEXTW2(m->ctx[i].title) && y > dc.y && y < dc.y + dc.font.height ? dc.sel : dc.norm; drawtext(m->ctx[i].title, col, False); if(col == dc.sel) { m->sel = &m->ctx[i]; sely = dc.y; }
Thanks that works perfectly
While you are it, can you post patch for other people if you are doing this against vanilla dwm-5.9? Would save me some time.
I'll prob do the keyboard part tomorrow
Sure thing, will be done soon.
Edit: here it is
:diff -rupN dwm/config.def.h dwm.new/config.def.h
--- dwm/config.def.h 2011-10-17 18:29:08.017535351 +0200
+++ dwm.new/config.def.h 2011-10-17 18:21:05.129088130 +0200
@@ -44,6 +44,18 @@ static const Layout layouts[] = {
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
+/* menus */
+#define MENUEND { NULL, NULL, NULL, {0} }
+#define MENUSEP(x) { x, NULL, NULL, {0} }
+
+/* title, submenu, function, argument */
+static const menuCtx rootMenu[] = {
+ MENUSEP("-------------"),
+ { "EMPTY", NULL, NULL, {0} },
+ MENUSEP("-------------"),
+ MENUEND,
+};
+
/* commands */
static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
static const char *termcmd[] = { "uxterm", NULL };
@@ -98,5 +110,6 @@ static Button buttons[] = {
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
+ { ClkRootWin, 0, Button3, togglemenu, {0} },
};
diff -rupN dwm/dwm.c dwm.new/dwm.c
--- dwm/dwm.c 2011-10-17 18:29:08.034202292 +0200
+++ dwm.new/dwm.c 2011-10-17 18:21:05.112421163 +0200
@@ -53,7 +53,7 @@
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
#define TAGMASK ((1 << LENGTH(tags)) - 1)
#define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height)
-
+#define TEXTW2(X) (textnw(X,strlen(X)))
/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { ColBorder, ColFG, ColBG, ColLast }; /* color */
@@ -151,7 +151,24 @@ typedef struct {
int monitor;
} Rule;
+typedef struct menuCtx {
+ char *title;
+ const struct menuCtx *ctx;
+ void (*func)(const Arg *);
+ const Arg arg;
+} menuCtx;
+typedef struct menu_t {
+ Window win;
+ int x, y, w, h;
+ Drawable drawable;
+ struct menu_t *next, *child;
+ const struct menuCtx *ctx, *sel;
+} menu_t;
+menu_t *menu = NULL;
+
/* function declarations */
+static void togglemenu(const Arg *arg);
+static void motionnotify(XEvent *e);
static void applyrules(Client *c);
static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact);
static void arrange(Monitor *m);
@@ -260,6 +277,7 @@ static void (*handler[LASTEvent]) (XEven
[ConfigureNotify] = configurenotify,
[DestroyNotify] = destroynotify,
[EnterNotify] = enternotify,
+ [MotionNotify] = motionnotify,
[Expose] = expose,
[FocusIn] = focusin,
[KeyPress] = keypress,
@@ -415,15 +433,231 @@ attachstack(Client *c) {
c->mon->stack = c;
}
+static menu_t* openmenupos( const menuCtx *ctx, int x, int y );
+static void closemenu( menu_t *target );
+static void
+updatemenu( menu_t *m, int x, int y ) {
+ Drawable dble = dc.drawable;
+ int ow = dc.w, oh = dc.h, ox = dc.x, oy = dc.y;
+ int sely = 0;
+ unsigned long *col;
+
+ if(!m) return;
+ const menuCtx *osel = m->sel;
+ m->sel = NULL;
+
+ dc.drawable = m->drawable;
+#ifdef XFT
+ XftDrawChange(dc.xftdrawable, dc.drawable);
+#endif
+ size_t i;
+ dc.x = 0; dc.y = 0;
+ dc.w = m->w; dc.h = m->h;
+
+ for(i = 0; m->ctx[i].title; ++i)
+ {
+ col = x > 0 && x < TEXTW2(m->ctx[i].title)
+ && y > dc.y && y < dc.y + dc.font.height ? dc.sel : dc.norm;
+ drawtext(m->ctx[i].title, col, False);
+ if(col == dc.sel) { m->sel = &m->ctx[i]; sely = dc.y; }
+ dc.y += dc.font.height;
+ }
+XCopyArea(dpy, dc.drawable, m->win, dc.gc, 0, 0, m->w, m->h, 0, 0);
+ XSync(dpy, False);
+
+ dc.w = ow; dc.h = oh; dc.x = ox; dc.y = oy;
+ dc.drawable = dble;
+#ifdef XFT
+ XftDrawChange(dc.xftdrawable, dc.drawable);
+#endif
+
+ if(m->sel && m->sel != osel)
+ {
+ if(m->child) { closemenu(m->child); m->child = NULL; }
+ if(m->sel->ctx != NULL)
+ m->child = openmenupos( m->sel->ctx, m->x + m->w, m->y + sely );
+ }
+
+}
+
+menu_t*
+wintomenu( Window win )
+{
+ menu_t *m;
+
+ if(!menu) return(NULL);
+ for( m = menu; m; m = m->next )
+ if(m->win == win) return(m);
+
+ return(NULL);
+}
+
+menu_t*
+ctxtomenu( const menuCtx *ctx )
+{
+ menu_t *m;
+
+ if(!menu) return(NULL);
+ for( m = menu; m; m = m->next )
+ if(m->ctx == ctx) return(m);
+
+ return(NULL);
+}
+
+static int
+createmenu( menu_t *m, const menuCtx *ctx, int x, int y ) {
+ size_t i;
+ if(ctxtomenu(ctx)) return(-1);
+
+ m->x = x;
+ m->y = y;
+ m->w = 0;
+ m->h = 0;
+ m->ctx = ctx;
+ m->sel = NULL;
+ m->child= NULL;
+
+ for(i = 0; m->ctx[i].title; ++i)
+ {
+ if(m->w < TEXTW2(m->ctx[i].title))
+ m->w = TEXTW2(m->ctx[i].title);
+ m->h += dc.font.height;
+ }
+ if(i == 0) return(-1);
+
+ XSetWindowAttributes wattr;
+ wattr.override_redirect = True;
+ wattr.background_pixmap = ParentRelative;
+ wattr.event_mask = ButtonPressMask|ExposureMask;
+
+ m->win = XCreateWindow(dpy, root, m->x, m->y, m->w, m->h, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWBackPixmap|CWOverrideRedirect|CWEventMask, &wattr);
+
+ if(m == menu)
+ XSelectInput(dpy, m->win, PointerMotionMask|ButtonPressMask);
+ else
+ XSelectInput(dpy, m->win, PointerMotionMask|ButtonPressMask|LeaveWindowMask);
+
+ XDefineCursor(dpy, m->win, cursor[CurNormal]);
+ XMapRaised(dpy, m->win);
+
+ m->drawable = XCreatePixmap(dpy, root, m->w, m->h, DefaultDepth(dpy, screen));
+ updatemenu(m, m->x, m->y);
+
+ if(selmon && selmon->sel)
+ { grabbuttons(selmon->sel,False); XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); XSync(dpy,False); }
+
+ return(0);
+}
+
+static menu_t*
+openmenupos( const menuCtx *ctx, int x, int y ) {
+ menu_t **m, *mm;
+
+ m = &menu;
+ mm = menu;
+ for(; mm; mm = mm->next)
+ m = &mm->next;
+
+ *m = calloc(1, sizeof(menu_t));
+ if(!*m)
+ return NULL;
+
+ (*m)->next = NULL;
+ if(createmenu(*m, ctx, x, y) == -1)
+ { free(*m); *m = NULL; }
+
+ return *m;
+}
+
+static menu_t*
+openmenu( const menuCtx *ctx ) {
+ int x, y;
+ getrootptr( &x, &y );
+ return openmenupos( ctx, x, y );
+}
+
+static void
+closemenu( menu_t *target )
+{
+ menu_t **m, *mm;
+
+ if(!target) return;
+
+ /* this is not valid child anymore */
+ for( mm = menu; mm; mm = mm->next )
+ if(mm->child == target) mm->child = NULL;
+
+ /* close childs */
+ for( mm = target->child; mm; mm = mm->child )
+ closemenu( mm );
+
+ /* remove */
+ m = &menu;
+ for( mm = menu; mm && mm->next && mm->next != target; mm = mm->next )
+ m = &mm;
+
+ (*m)->next = target->next;
+
+ XFreePixmap(dpy, target->drawable);
+ XDestroyWindow(dpy, target->win);
+ free(target);
+ XSync(dpy, False);
+}
+
+static void
+closemenus(void) {
+ if(!menu) return;
+
+ menu_t *m = menu, *next = NULL;
+ while(m)
+ {
+ XDestroyWindow(dpy, m->win);
+
+ next = m->next; free(m);
+ m = next;
+ }
+ XSync(dpy, False);
+ menu = NULL;
+}
+
+void
+togglemenu(const Arg *arg) {
+ if(!menu)
+ openmenu(&rootMenu[0]);
+ else
+ closemenus();
+}
+
+static void
+buttonmenu( menu_t *m, int x, int y )
+{
+ if(!m) return;
+ updatemenu(m, x, y);
+ if(!m->sel) return;
+ if(!m->sel->func) return;
+
+ m->sel->func(&m->sel->arg);
+ closemenus();
+}
+
void
buttonpress(XEvent *e) {
unsigned int i, x, click;
Arg arg = {0};
Client *c;
Monitor *m;
+ menu_t *mm;
XButtonPressedEvent *ev = &e->xbutton;
-
+
click = ClkRootWin;
+ if(ev->button == Button1)
+ {
+ if(menu) {
+ if(!(mm = wintomenu(ev->window)))
+ closemenus();
+ else { buttonmenu(mm, ev->x, ev->y); return; }
+ }
+ }
/* focus monitor if necessary */
if((m = wintomon(ev->window)) && m != selmon) {
unfocus(selmon->sel, True);
@@ -457,6 +691,19 @@ buttonpress(XEvent *e) {
}
void
+motionnotify(XEvent *e) {
+ menu_t *mm;
+ XMotionEvent *ev = &e->xmotion;
+
+ if( (mm = wintomenu(ev->window)) )
+ {
+ updatemenu(mm, ev->x, ev->y);
+ return;
+ }
+}
+
+
+void
checkotherwm(void) {
xerrorxlib = XSetErrorHandler(xerrorstart);
/* this causes an error if some other window manager is running */
Binary files dwm/.hg/dirstate and dwm.new/.hg/dirstate differ
how to apply:
save and rename to menu.patch or something
go into your dwm directory and do:
patch -p1 < /path/to/patchfile
I've never made a patch before but it applies fine when I tested it
Last edited by vanvalium (2011-10-17 16:44:56)
Offline
Edit: here it is
:diff -rupN dwm/config.def.h dwm.new/config.def.h --- dwm/config.def.h 2011-10-17 18:29:08.017535351 +0200 +++ dwm.new/config.def.h 2011-10-17 18:21:05.129088130 +0200 @@ -44,6 +44,18 @@ static const Layout layouts[] = { /* helper for spawning shell commands in the pre dwm-5.0 fashion */ #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } +/* menus */ +#define MENUEND { NULL, NULL, NULL, {0} } +#define MENUSEP(x) { x, NULL, NULL, {0} } + +/* title, submenu, function, argument */ +static const menuCtx rootMenu[] = { + MENUSEP("-------------"), + { "EMPTY", NULL, NULL, {0} }, + MENUSEP("-------------"), + MENUEND, +}; + /* commands */ static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; static const char *termcmd[] = { "uxterm", NULL }; @@ -98,5 +110,6 @@ static Button buttons[] = { { ClkTagBar, 0, Button3, toggleview, {0} }, { ClkTagBar, MODKEY, Button1, tag, {0} }, { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + { ClkRootWin, 0, Button3, togglemenu, {0} }, }; diff -rupN dwm/dwm.c dwm.new/dwm.c --- dwm/dwm.c 2011-10-17 18:29:08.034202292 +0200 +++ dwm.new/dwm.c 2011-10-17 18:21:05.112421163 +0200 @@ -53,7 +53,7 @@ #define HEIGHT(X) ((X)->h + 2 * (X)->bw) #define TAGMASK ((1 << LENGTH(tags)) - 1) #define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height) - +#define TEXTW2(X) (textnw(X,strlen(X))) /* enums */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ @@ -151,7 +151,24 @@ typedef struct { int monitor; } Rule; +typedef struct menuCtx { + char *title; + const struct menuCtx *ctx; + void (*func)(const Arg *); + const Arg arg; +} menuCtx; +typedef struct menu_t { + Window win; + int x, y, w, h; + Drawable drawable; + struct menu_t *next, *child; + const struct menuCtx *ctx, *sel; +} menu_t; +menu_t *menu = NULL; + /* function declarations */ +static void togglemenu(const Arg *arg); +static void motionnotify(XEvent *e); static void applyrules(Client *c); static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); static void arrange(Monitor *m); @@ -260,6 +277,7 @@ static void (*handler[LASTEvent]) (XEven [ConfigureNotify] = configurenotify, [DestroyNotify] = destroynotify, [EnterNotify] = enternotify, + [MotionNotify] = motionnotify, [Expose] = expose, [FocusIn] = focusin, [KeyPress] = keypress, @@ -415,15 +433,231 @@ attachstack(Client *c) { c->mon->stack = c; } +static menu_t* openmenupos( const menuCtx *ctx, int x, int y ); +static void closemenu( menu_t *target ); +static void +updatemenu( menu_t *m, int x, int y ) { + Drawable dble = dc.drawable; + int ow = dc.w, oh = dc.h, ox = dc.x, oy = dc.y; + int sely = 0; + unsigned long *col; + + if(!m) return; + const menuCtx *osel = m->sel; + m->sel = NULL; + + dc.drawable = m->drawable; +#ifdef XFT + XftDrawChange(dc.xftdrawable, dc.drawable); +#endif + size_t i; + dc.x = 0; dc.y = 0; + dc.w = m->w; dc.h = m->h; + + for(i = 0; m->ctx[i].title; ++i) + { + col = x > 0 && x < TEXTW2(m->ctx[i].title) + && y > dc.y && y < dc.y + dc.font.height ? dc.sel : dc.norm; + drawtext(m->ctx[i].title, col, False); + if(col == dc.sel) { m->sel = &m->ctx[i]; sely = dc.y; } + dc.y += dc.font.height; + } +XCopyArea(dpy, dc.drawable, m->win, dc.gc, 0, 0, m->w, m->h, 0, 0); + XSync(dpy, False); + + dc.w = ow; dc.h = oh; dc.x = ox; dc.y = oy; + dc.drawable = dble; +#ifdef XFT + XftDrawChange(dc.xftdrawable, dc.drawable); +#endif + + if(m->sel && m->sel != osel) + { + if(m->child) { closemenu(m->child); m->child = NULL; } + if(m->sel->ctx != NULL) + m->child = openmenupos( m->sel->ctx, m->x + m->w, m->y + sely ); + } + +} + +menu_t* +wintomenu( Window win ) +{ + menu_t *m; + + if(!menu) return(NULL); + for( m = menu; m; m = m->next ) + if(m->win == win) return(m); + + return(NULL); +} + +menu_t* +ctxtomenu( const menuCtx *ctx ) +{ + menu_t *m; + + if(!menu) return(NULL); + for( m = menu; m; m = m->next ) + if(m->ctx == ctx) return(m); + + return(NULL); +} + +static int +createmenu( menu_t *m, const menuCtx *ctx, int x, int y ) { + size_t i; + if(ctxtomenu(ctx)) return(-1); + + m->x = x; + m->y = y; + m->w = 0; + m->h = 0; + m->ctx = ctx; + m->sel = NULL; + m->child= NULL; + + for(i = 0; m->ctx[i].title; ++i) + { + if(m->w < TEXTW2(m->ctx[i].title)) + m->w = TEXTW2(m->ctx[i].title); + m->h += dc.font.height; + } + if(i == 0) return(-1); + + XSetWindowAttributes wattr; + wattr.override_redirect = True; + wattr.background_pixmap = ParentRelative; + wattr.event_mask = ButtonPressMask|ExposureMask; + + m->win = XCreateWindow(dpy, root, m->x, m->y, m->w, m->h, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWBackPixmap|CWOverrideRedirect|CWEventMask, &wattr); + + if(m == menu) + XSelectInput(dpy, m->win, PointerMotionMask|ButtonPressMask); + else + XSelectInput(dpy, m->win, PointerMotionMask|ButtonPressMask|LeaveWindowMask); + + XDefineCursor(dpy, m->win, cursor[CurNormal]); + XMapRaised(dpy, m->win); + + m->drawable = XCreatePixmap(dpy, root, m->w, m->h, DefaultDepth(dpy, screen)); + updatemenu(m, m->x, m->y); + + if(selmon && selmon->sel) + { grabbuttons(selmon->sel,False); XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); XSync(dpy,False); } + + return(0); +} + +static menu_t* +openmenupos( const menuCtx *ctx, int x, int y ) { + menu_t **m, *mm; + + m = &menu; + mm = menu; + for(; mm; mm = mm->next) + m = &mm->next; + + *m = calloc(1, sizeof(menu_t)); + if(!*m) + return NULL; + + (*m)->next = NULL; + if(createmenu(*m, ctx, x, y) == -1) + { free(*m); *m = NULL; } + + return *m; +} + +static menu_t* +openmenu( const menuCtx *ctx ) { + int x, y; + getrootptr( &x, &y ); + return openmenupos( ctx, x, y ); +} + +static void +closemenu( menu_t *target ) +{ + menu_t **m, *mm; + + if(!target) return; + + /* this is not valid child anymore */ + for( mm = menu; mm; mm = mm->next ) + if(mm->child == target) mm->child = NULL; + + /* close childs */ + for( mm = target->child; mm; mm = mm->child ) + closemenu( mm ); + + /* remove */ + m = &menu; + for( mm = menu; mm && mm->next && mm->next != target; mm = mm->next ) + m = &mm; + + (*m)->next = target->next; + + XFreePixmap(dpy, target->drawable); + XDestroyWindow(dpy, target->win); + free(target); + XSync(dpy, False); +} + +static void +closemenus(void) { + if(!menu) return; + + menu_t *m = menu, *next = NULL; + while(m) + { + XDestroyWindow(dpy, m->win); + + next = m->next; free(m); + m = next; + } + XSync(dpy, False); + menu = NULL; +} + +void +togglemenu(const Arg *arg) { + if(!menu) + openmenu(&rootMenu[0]); + else + closemenus(); +} + +static void +buttonmenu( menu_t *m, int x, int y ) +{ + if(!m) return; + updatemenu(m, x, y); + if(!m->sel) return; + if(!m->sel->func) return; + + m->sel->func(&m->sel->arg); + closemenus(); +} + void buttonpress(XEvent *e) { unsigned int i, x, click; Arg arg = {0}; Client *c; Monitor *m; + menu_t *mm; XButtonPressedEvent *ev = &e->xbutton; - + click = ClkRootWin; + if(ev->button == Button1) + { + if(menu) { + if(!(mm = wintomenu(ev->window))) + closemenus(); + else { buttonmenu(mm, ev->x, ev->y); return; } + } + } /* focus monitor if necessary */ if((m = wintomon(ev->window)) && m != selmon) { unfocus(selmon->sel, True); @@ -457,6 +691,19 @@ buttonpress(XEvent *e) { } void +motionnotify(XEvent *e) { + menu_t *mm; + XMotionEvent *ev = &e->xmotion; + + if( (mm = wintomenu(ev->window)) ) + { + updatemenu(mm, ev->x, ev->y); + return; + } +} + + +void checkotherwm(void) { xerrorxlib = XSetErrorHandler(xerrorstart); /* this causes an error if some other window manager is running */ Binary files dwm/.hg/dirstate and dwm.new/.hg/dirstate differ
how to apply:
save and rename to menu.patch or something
go into your dwm directory and do:patch -p1 < /path/to/patchfile
I've never made a patch before but it applies fine when I tested it
Great, thanks
The patch looks quite "different", but if it's tested and works, then it's good.
I'll mirror it to my gist.
Offline
Offline
'cause you are using statuscolors patch.
after replacing dc.norm with dc.colors[0] and dc.sel with dc.colors[1] it should work.
Arch64/DWM || My Dropbox referral link
Offline
The patch prob won't work very well on modified dwm (with other patches)
Your manual patching was almost there. You forgot this from top of the dwm.c
#define TEXTW2(X) (textnw(X, strlen(X)))
Also do you use more colors patch? If you do then there is no dc.norm or dc.sel anymore, instead you need to use dc.colors[0] and dc.colors[1]
E: Ninja'd by JokerBoy
Last edited by Cloudef (2011-10-17 19:52:46)
Offline
vanvalium wrote:I've never made a patch before but it applies fine when I tested it
Great, thanks
The patch looks quite "different", but if it's tested and works, then it's good.
I'll mirror it to my gist.
Some other testers might be useful of course.
I patched it against a fresh mercurial clone so it should be working.
Why not send it to the ML as well? Might be some people who enjoy it.
Offline
Some other testers might be useful of course.
I patched it against a fresh mercurial clone so it should be working.
I was bored, so I just tested this by downloading the patch from cloudef's gist and patched it against both latest hg tip and latest stable release i.e. v5.9, and it fails in both cases...
martin@arch ~ % cd dwm-5.9
martin@arch ~/dwm-5.9 % patch < ../gistfile1.diff
patching file config.def.h
Hunk #2 FAILED at 110.
1 out of 2 hunks FAILED -- saving rejects to file config.def.h.rej
patching file dwm.c
Hunk #2 succeeded at 151 with fuzz 1.
Hunk #3 FAILED at 277.
Hunk #4 FAILED at 432.
Hunk #5 succeeded at 475 with fuzz 2 (offset 1 line).
patch unexpectedly ends in middle of line
2 out of 5 hunks FAILED -- saving rejects to file dwm.c.rej
patch unexpectedly ends in middle of line
martin@arch ~/dwm-5.9 % cd
martin@arch ~ % hg clone http://hg.suckless.org/dwm
destination directory: dwm
requesting all changes
adding changesets
adding manifests
adding file changes
added 1576 changesets with 2973 changes to 50 files (+1 heads)
updating to branch default
12 files updated, 0 files merged, 0 files removed, 0 files unresolved
martin@arch ~ % cd dwm
martin@arch ~/dwm % patch < ../gistfile1.diff
patching file config.def.h
Hunk #2 FAILED at 110.
1 out of 2 hunks FAILED -- saving rejects to file config.def.h.rej
patching file dwm.c
Hunk #2 succeeded at 151 with fuzz 1.
Hunk #3 FAILED at 277.
Hunk #4 FAILED at 432.
Hunk #5 succeeded at 474 with fuzz 2.
patch unexpectedly ends in middle of line
2 out of 5 hunks FAILED -- saving rejects to file dwm.c.rej
patch unexpectedly ends in middle of line
Last edited by mhertz (2011-10-17 23:23:34)
Offline
Offline
Guys I edited this and works
col = x > 0 && x < TEXTW2(m->ctx[i].title)
&& y > dc.y && y < dc.y + dc.font.height ? dc.colors[1] : dc.colors[0];
drawtext(m->ctx[i].title, col, False);
if(col == dc.colors[1]) { m->sel = &m->ctx[i]; sely = dc.y; }
dc.y += dc.font.height;
}
Thanks to all!
I have one last question on the structure for the defaults menu
/* menus */
#define MENUEND { NULL, NULL, NULL, {0} }
#define MENUSEP(x) { x, NULL, NULL, {0} }
/* title, submenu, function, argument */
static const menuCtx internetMenu[] = {
{ "Chromium ", NULL, spawn, {.v = chromium } },
MENUSEP("--------"),
MENUEND,
};
static const menuCtx rootMenu[] = {
MENUSEP("-------------"),
{ "Internet >", &internetMenu[0], NULL, {0} },
MENUSEP("-------------"),
MENUEND,
};
wm build options:
CFLAGS = -std=c99 -pedantic -Wall -Os -I. -I/usr/include -I/usr/X11R6/include -DVERSION="5.9" -DXINERAMA
LDFLAGS = -s -L/usr/lib -lc -L/usr/X11R6/lib -lX11 -L/usr/X11R6/lib -lXinerama
CC = cc
CC dwm.c
In file included from dwm.c:332:0:
config.h:66:38: error: ‘chromium’ undeclared here (not in a function)
make: *** [dwm.o] Error 1
Offline
I was bored, so I just tested this by downloading the patch from cloudef's gist and patched it against both latest hg tip and latest stable release i.e. v5.9, and it fails in both cases...
I tried the gist patch and it doesn't work, the one I made on my harddrive does however.
When I'm home I'll look into it again.
It'd probably help if someone who knows more about patches than me (basically anyone) could look into it.
wm build options: CFLAGS = -std=c99 -pedantic -Wall -Os -I. -I/usr/include -I/usr/X11R6/include -DVERSION="5.9" -DXINERAMA LDFLAGS = -s -L/usr/lib -lc -L/usr/X11R6/lib -lX11 -L/usr/X11R6/lib -lXinerama CC = cc CC dwm.c In file included from dwm.c:332:0: config.h:66:38: error: ‘chromium’ undeclared here (not in a function) make: *** [dwm.o] Error 1
you need this in your config before the menu
static const char *chromium[] = {"chromium", NULL };
Offline
Offline
@vanvalium
Thanks dude!
I had it below the menu
guys now have litle problem whit the MENUSEP("--------"),
/* menus */
#define MENUEND { NULL, NULL, NULL, {0} }
#define MENUSEP(x) { x, NULL, NULL, {0} }
/* title, submenu, function, argument */
static const menuCtx internetMenu[] = {
{ "chromium ", NULL, spawn, {.v = chromium } },
{ "skype ", NULL, spawn, {.v = skype } },
MENUEND,
};
static const menuCtx gimpMenu[] = {
{ "Gimp", NULL, spawn, {.v = gimp } },
MENUEND,
};
static const menuCtx rootMenu[] = {
{ "Internet >", &internetMenu[0], NULL, {0} },
{ "Gimp >", &gimpMenu[0], NULL, {0} },
MENUEND,
};
and with the MENUSEP("--------"),
/* menus */
#define MENUEND { NULL, NULL, NULL, {0} }
#define MENUSEP(x) { x, NULL, NULL, {0} }
/* title, submenu, function, argument */
static const menuCtx internetMenu[] = {
{ "chromium ", NULL, spawn, {.v = chromium } },
MENUSEP("--------"),
{ "skype ", NULL, spawn, {.v = skype } },
MENUEND,
};
static const menuCtx gimpMenu[] = {
{ "Gimp", NULL, spawn, {.v = gimp } },
MENUEND,
};
static const menuCtx rootMenu[] = {
{ "Internet >", &internetMenu[0], NULL, {0} },
MENUSEP("--------"),
{ "Gimp >", &gimpMenu[0], NULL, {0} },
MENUEND,
};
Last edited by ivoarch (2011-10-18 17:48:36)
Offline
Hmm, are you using non XFT fonts? I haven't tried it without them, if it's indeed non XFT, I'll check and fix it. If it's XFT, I need to know your current font and size so I can fix it.
I added basic keyboard support too, can't be configured from config.h currently, but the default bindings get the work done atm.
https://github.com/Cloudef/dwm-fork/com … 808bbcab52
Arrow keys for moving, enter for accept and escape(or your toggle binding) for closing.
Offline
How did you create the patch?
diff -rupN dwm/ dwm.new/ > menu.patch
That's what my search engine gave me after 2 minutes of searching
I added basic keyboard support too, can't be configured from config.h currently, but the default bindings get the work done atm.
https://github.com/Cloudef/dwm-fork/com … 808bbcab52
Arrow keys for moving, enter for accept and escape(or your toggle binding) for closing.
Nice I'll try that
Offline
You should upload that menu.patch somewhere, not sharing it with c/p.
Arch64/DWM || My Dropbox referral link
Offline
Hi, I use "-*-terminus-medium-r-*-*-14-*-*-*-*-*-*-*";
Ok, there is bug in updatemenu that works under XFT since my implentation of XFT text in drawtext function isn't 100% identical to default text drawing.
So, In updatemenu function, take out
dc.h = m->h;
and before
drawtext(m->ctx[i].title, col, False);
insert:
dc.h = dc.font.height;
@vanvalium
Try uploading the patch somewhere, like JokerBoy mentioned.
Last edited by Cloudef (2011-10-18 19:35:54)
Offline