You are not logged in.

#351 2011-10-15 20:15:53

stlarch
Member
From: hell
Registered: 2010-12-25
Posts: 1,265

Re: DWM Hackers Unite! Share (or request) dwm patches.

mhertz wrote:

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.

mhertz wrote:

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

#352 2011-10-15 21:58:29

mhertz
Member
From: Denmark
Registered: 2010-06-19
Posts: 681

Re: DWM Hackers Unite! Share (or request) dwm patches.

stlarch wrote:

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 smile

Last edited by mhertz (2011-10-15 22:00:29)

Offline

#353 2011-10-16 05:44:11

stlarch
Member
From: hell
Registered: 2010-12-25
Posts: 1,265

Re: DWM Hackers Unite! Share (or request) dwm patches.

mhertz wrote:

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

#354 2011-10-16 16:59:06

ivoarch
Member
Registered: 2011-03-31
Posts: 436

Re: DWM Hackers Unite! Share (or request) dwm patches.

Cloudef wrote:

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)


I love GnuEmacs, GnuScreen, ratpoison, and conkeror.
Github )||( Weblog

Offline

#355 2011-10-16 23:43:11

mhertz
Member
From: Denmark
Registered: 2010-06-19
Posts: 681

Re: DWM Hackers Unite! Share (or request) dwm patches.

stlarch wrote:

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

#356 2011-10-17 12:00:31

Cloudef
Member
Registered: 2010-10-12
Posts: 636

Re: DWM Hackers Unite! Share (or request) dwm patches.

ivoarch wrote:

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

#357 2011-10-17 15:42:36

vanvalium
Member
From: Austria
Registered: 2010-10-09
Posts: 86

Re: DWM Hackers Unite! Share (or request) dwm patches.

Cloudef wrote:

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)))
Cloudef wrote:

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

Cloudef wrote:

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

Cloudef wrote:
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

#358 2011-10-17 15:54:36

Cloudef
Member
Registered: 2010-10-12
Posts: 636

Re: DWM Hackers Unite! Share (or request) dwm patches.

vanvalium wrote:

*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 fix

I 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 smile

Last edited by Cloudef (2011-10-17 15:56:21)

Offline

#359 2011-10-17 16:06:10

vanvalium
Member
From: Austria
Registered: 2010-10-09
Posts: 86

Re: DWM Hackers Unite! Share (or request) dwm patches.

Cloudef wrote:

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 smile

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

#360 2011-10-17 17:24:38

Cloudef
Member
Registered: 2010-10-12
Posts: 636

Re: DWM Hackers Unite! Share (or request) dwm patches.

vanvalium wrote:

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 smile
The patch looks quite "different", but if it's tested and works, then it's good.
I'll mirror it to my gist.

Offline

#361 2011-10-17 18:41:32

ivoarch
Member
Registered: 2011-03-31
Posts: 436

Re: DWM Hackers Unite! Share (or request) dwm patches.

I added the patch manual to my dwm.c , but I get errors whit updatemenu

FluxBB bbcode test

the patch not work for me

tYXVxOQ

Last edited by ivoarch (2011-10-17 18:54:01)


I love GnuEmacs, GnuScreen, ratpoison, and conkeror.
Github )||( Weblog

Offline

#362 2011-10-17 19:50:18

JokerBoy
Member
From: România
Registered: 2009-09-24
Posts: 641

Re: DWM Hackers Unite! Share (or request) dwm patches.

'cause you are using statuscolors patch.

after replacing dc.norm with dc.colors[0] and dc.sel with dc.colors[1] it should work.

Offline

#363 2011-10-17 19:52:02

Cloudef
Member
Registered: 2010-10-12
Posts: 636

Re: DWM Hackers Unite! Share (or request) dwm patches.

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

#364 2011-10-17 21:50:06

vanvalium
Member
From: Austria
Registered: 2010-10-09
Posts: 86

Re: DWM Hackers Unite! Share (or request) dwm patches.

Cloudef wrote:
vanvalium wrote:

I've never made a patch before but it applies fine when I tested it

Great, thanks smile
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

#365 2011-10-17 23:22:40

mhertz
Member
From: Denmark
Registered: 2010-06-19
Posts: 681

Re: DWM Hackers Unite! Share (or request) dwm patches.

vanvalium wrote:

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

#366 2011-10-18 11:04:49

Cloudef
Member
Registered: 2010-10-12
Posts: 636

Re: DWM Hackers Unite! Share (or request) dwm patches.

I guess the patch needs to do again, it does not look quite right. With diff you can do it with -U option, but I've always used git format-patch myself or some other VCS feature of it.

Offline

#367 2011-10-18 11:34:28

ivoarch
Member
Registered: 2011-03-31
Posts: 436

Re: DWM Hackers Unite! Share (or request) dwm patches.

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    

I love GnuEmacs, GnuScreen, ratpoison, and conkeror.
Github )||( Weblog

Offline

#368 2011-10-18 15:30:14

vanvalium
Member
From: Austria
Registered: 2010-10-09
Posts: 86

Re: DWM Hackers Unite! Share (or request) dwm patches.

mhertz wrote:

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

#369 2011-10-18 16:21:07

Cloudef
Member
Registered: 2010-10-12
Posts: 636

Re: DWM Hackers Unite! Share (or request) dwm patches.

It'd probably help if someone who knows more about patches than me (basically anyone) could look into it.

How did you create the patch?
Also been busy today, could not do the keyboard functionality yet.

Offline

#370 2011-10-18 17:41:36

ivoarch
Member
Registered: 2011-03-31
Posts: 436

Re: DWM Hackers Unite! Share (or request) dwm patches.

@vanvalium
Thanks dude!
I had it below the menu

guys now have litle problem whit the  MENUSEP("--------"),  sad

 
/* 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,
}; 

 

tYXZhaQ

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,
};   

tYXZhZg

Last edited by ivoarch (2011-10-18 17:48:36)


I love GnuEmacs, GnuScreen, ratpoison, and conkeror.
Github )||( Weblog

Offline

#371 2011-10-18 18:21:58

Cloudef
Member
Registered: 2010-10-12
Posts: 636

Re: DWM Hackers Unite! Share (or request) dwm patches.

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

#372 2011-10-18 18:44:48

ivoarch
Member
Registered: 2011-03-31
Posts: 436

Re: DWM Hackers Unite! Share (or request) dwm patches.

Hi, I use "-*-terminus-medium-r-*-*-14-*-*-*-*-*-*-*";


I love GnuEmacs, GnuScreen, ratpoison, and conkeror.
Github )||( Weblog

Offline

#373 2011-10-18 19:15:46

vanvalium
Member
From: Austria
Registered: 2010-10-09
Posts: 86

Re: DWM Hackers Unite! Share (or request) dwm patches.

Cloudef wrote:

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

#374 2011-10-18 19:27:18

JokerBoy
Member
From: România
Registered: 2009-09-24
Posts: 641

Re: DWM Hackers Unite! Share (or request) dwm patches.

You should upload that menu.patch somewhere, not sharing it with c/p. tongue

Offline

#375 2011-10-18 19:34:48

Cloudef
Member
Registered: 2010-10-12
Posts: 636

Re: DWM Hackers Unite! Share (or request) dwm patches.

ivoarch wrote:

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

Board footer

Powered by FluxBB