You are not logged in.

#1026 2012-12-09 13:13:57

illusionist
Member
From: localhost
Registered: 2012-04-03
Posts: 498

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

cxld wrote:

The focusonclick patch at dwm.suckless.org does not work with resizemouse and the movemouse functions because of the Async changes in the patch. Does anyone have a version of the focusonclick patch the works with resizemouse and movemouse?

Disable focus follow mouse

Easy as pie...


  Never argue with stupid people,They will drag you down to their level and then beat you with experience.--Mark Twain
@github

Offline

#1027 2012-12-09 18:03:52

cxld
Member
Registered: 2012-12-09
Posts: 8

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

illusionist wrote:

That method has its own problems as noted in the link. For example, if I am focused on Window A and I want to highlight some text on Window B, I cannot simply left click on Window B and drag my mouse down. I have to left click once to gain focus then left click again to drag down. The Sync changes made by the focusonclick patch resolve this but make it impossible to do things like resizemouse. I do not want to have to double click a window every time I want to interact with it. I use floating windows infrequently enough that I would probably rather live without resizemouse than have to double click a window to properly focus it.

Last edited by cxld (2012-12-09 18:06:51)

Offline

#1028 2012-12-10 09:44:23

illusionist
Member
From: localhost
Registered: 2012-04-03
Posts: 498

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

@cxld
Post the patches you are trying to apply. I'll take a look at those.

Last edited by illusionist (2012-12-10 09:44:41)


  Never argue with stupid people,They will drag you down to their level and then beat you with experience.--Mark Twain
@github

Offline

#1029 2012-12-11 11:07:46

Ypnose
Member
From: Jailed in the shell
Registered: 2011-04-21
Posts: 353
Website

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

Hi,
I want to use "selected" color only for tags. Do you know where could I remove the "selected" color only for window name in the bar?


Github -- My terminal font Envypn

Offline

#1030 2012-12-11 11:19:56

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

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

In drawbar(), you should change this part:

       if(m->sel) {
           col = dc.colors[ m == selmon ? 1 : 0 ];
           drawtext(m->sel->name, col, True);
       }
       else

You can remove the "col =" line and change col in drawtext to, for example, dc.norm or dc.colors[0] (if you're using statuscolors patch, that is)

EDIT: Your code might look a tad different if you're not using the statuscolors patch.

Last edited by Unia (2012-12-11 11:20:49)


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#1031 2012-12-11 11:49:01

Ypnose
Member
From: Jailed in the shell
Registered: 2011-04-21
Posts: 353
Website

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

Good work! Thanks.
Changed the following lines:

if(m->sel) {
drawtext(m->sel->name, dc.colors[2], True);

Github -- My terminal font Envypn

Offline

#1032 2012-12-11 11:51:50

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

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

Woohoo, I just helped my first case with DWM hacking big_smile


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#1033 2012-12-11 22:49:42

cxld
Member
Registered: 2012-12-09
Posts: 8

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

@illusionist

The patch I'm using is on the suckless homepage: http://dwm.suckless.org/patches/focusonclick

Offline

#1034 2012-12-12 03:28:48

illusionist
Member
From: localhost
Registered: 2012-04-03
Posts: 498

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

cxld wrote:

@illusionist

The patch I'm using is on the suckless homepage: http://dwm.suckless.org/patches/focusonclick

Try this patch.


  Never argue with stupid people,They will drag you down to their level and then beat you with experience.--Mark Twain
@github

Offline

#1035 2012-12-12 05:49:27

cxld
Member
Registered: 2012-12-09
Posts: 8

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

@illusionist

illusionist wrote:

Try this patch.

I just pulled that patch off the dwm mailing list, and it seems to work well without any caveats so far. Thanks for the help.

Offline

#1036 2012-12-12 06:33:48

illusionist
Member
From: localhost
Registered: 2012-04-03
Posts: 498

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

Unia wrote:

Woohoo, I just helped my first case with DWM hacking big_smile

Forgot me big_smile


  Never argue with stupid people,They will drag you down to their level and then beat you with experience.--Mark Twain
@github

Offline

#1037 2012-12-15 00:13:56

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

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

Hello friends,

I want my statusbar and system tray to stay on monitor1 in a multi-monitor setup. I have found Jokerboy's statusmon patch that does just this for the statusbar - now it's up to me to apply the same method to the system tray.

I have already stopped the tray from appearing on monitor2, but it still dissapears from monitor1. I can't seem to get it to stay on monitor1 when I move focus to monitor2. Can you help me?

EDIT: I think I have to do something with all the resizebarwin(selmon) calls, or the updatesystray() function? I also found this older patch for a system tray online that only puts it on the first monitor: https://github.com/kcirick/dwm/blob/mas … stray.diff

Here's my current system tray patch:

--- dwm.c.orig	2012-05-26 15:42:46.462912626 +0200
+++ b/dwm-6.0/dwm.c	2012-05-26 15:42:15.122913347 +0200
@@ -56,12 +56,30 @@
 #define TAGMASK                 ((1 << LENGTH(tags)) - 1)
 #define TEXTW(X)                (textnw(X, strlen(X)) + dc.font.height)
 
+#define SYSTEM_TRAY_REQUEST_DOCK    0
+#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0
+
+/* XEMBED messages */
+#define XEMBED_EMBEDDED_NOTIFY      0
+#define XEMBED_WINDOW_ACTIVATE      1
+#define XEMBED_FOCUS_IN             4
+#define XEMBED_MODALITY_ON         10
+
+#define XEMBED_MAPPED              (1 << 0)
+#define XEMBED_WINDOW_ACTIVATE      1
+#define XEMBED_WINDOW_DEACTIVATE    2
+
+#define VERSION_MAJOR               0
+#define VERSION_MINOR               0
+#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
+
 /* enums */
 enum { CurNormal, CurResize, CurMove, CurLast };        /* cursor */
 enum { ColBorder, ColFG, ColBG, ColLast };              /* color */
-enum { NetSupported, NetWMName, NetWMState,
-       NetWMFullscreen, NetActiveWindow, NetWMWindowType,
-       NetWMWindowTypeDialog, NetLast };     /* EWMH atoms */
+enum { NetSupported, NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation,
+	   NetWMName, NetWMState, NetWMFullscreen, NetActiveWindow, NetWMWindowType,
+	   NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */
+enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
 enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
 enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
        ClkClientWin, ClkRootWin, ClkLast };             /* clicks */
@@ -165,6 +183,12 @@
 	int monitor;
 } Rule;
 
+typedef struct Systray   Systray;
+struct Systray {
+	Window win;
+	Client *icons;
+};
+
 /* function declarations */
 static void applyrules(Client *c);
 static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact);
@@ -197,9 +221,11 @@
 static void focusin(XEvent *e);
 static void focusmon(const Arg *arg);
 static void focusstack(const Arg *arg);
+static Atom getatomprop(Client *c, Atom prop);
 static XftColor getcolor(const char *colstr);
 static Bool getrootptr(int *x, int *y);
 static long getstate(Window w);
+static unsigned int getsystraywidth();
 static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
 static void grabbuttons(Client *c, Bool focused);
 static void grabkeys(void);
@@ -218,13 +244,16 @@
 static void propertynotify(XEvent *e);
 static void quit(const Arg *arg);
 static Monitor *recttomon(int x, int y, int w, int h);
+static void removesystrayicon(Client *i);
 static void resize(Client *c, int x, int y, int w, int h, Bool interact);
+static void resizebarwin(Monitor *m);
 static void resizeclient(Client *c, int x, int y, int w, int h);
 static void resizemouse(const Arg *arg);
+static void resizerequest(XEvent *e);
 static void restack(Monitor *m);
 static void run(void);
 static void scan(void);
-static Bool sendevent(Client *c, Atom proto);
+static Bool sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4);
 static void sendmon(Client *c, Monitor *m);
 static void setclientstate(Client *c, long state);
 static void setfocus(Client *c);
@@ -252,12 +281,16 @@
 static void updatenumlockmask(void);
 static void updatesizehints(Client *c);
 static void updatestatus(void);
+static void updatesystray(void);
+static void updatesystrayicongeom(Client *i, int w, int h);
+static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
 static void updatewindowtype(Client *c);
 static void updatetitle(Client *c);
 static void updatewmhints(Client *c);
 static void view(const Arg *arg);
 static Client *wintoclient(Window w);
 static Monitor *wintomon(Window w);
+static Client *wintosystrayicon(Window w);
 static int xerror(Display *dpy, XErrorEvent *ee);
 static int xerrordummy(Display *dpy, XErrorEvent *ee);
 static int xerrorstart(Display *dpy, XErrorEvent *ee);
@@ -265,6 +298,8 @@
 static void bstack(Monitor *m);
 
 /* variables */
+static Systray *systray = NULL;
+static unsigned long systrayorientation = _NET_SYSTEM_TRAY_ORIENTATION_HORZ;
 static const char broken[] = "broken";
 static char stext[256];
 static int screen;
@@ -286,9 +321,10 @@
 	[MapRequest] = maprequest,
 	[MotionNotify] = motionnotify,
 	[PropertyNotify] = propertynotify,
+	[ResizeRequest] = resizerequest,
 	[UnmapNotify] = unmapnotify
 };
-static Atom wmatom[WMLast], netatom[NetLast];
+static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
 static Bool running = True;
 static Cursor cursor[CurLast];
 static Display *dpy;
@@ -506,6 +542,11 @@
 	XFreeCursor(dpy, cursor[CurMove]);
 	while(mons)
 		cleanupmon(mons);
+	if(showsystray) {
+		XUnmapWindow(dpy, systray->win);
+		XDestroyWindow(dpy, systray->win);
+		free(systray);
+	}
 	XSync(dpy, False);
 	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
 }
@@ -542,9 +583,48 @@
 
 void
 clientmessage(XEvent *e) {
+	XWindowAttributes wa;
+	XSetWindowAttributes swa;
 	XClientMessageEvent *cme = &e->xclient;
 	Client *c = wintoclient(cme->window);
 
+	if(showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) {
+		/* add systray icons */
+		if(cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
+			if(!(c = (Client *)calloc(1, sizeof(Client))))
+				die("fatal: could not malloc() %u bytes\n", sizeof(Client));
+			c->win = cme->data.l[2];
+			c->mon = selmon;
+			c->next = systray->icons;
+			systray->icons = c;
+			XGetWindowAttributes(dpy, c->win, &wa);
+			c->x = c->oldx = c->y = c->oldy = 0;
+			c->w = c->oldw = wa.width;
+			c->h = c->oldh = wa.height;
+			c->oldbw = wa.border_width;
+			c->bw = 0;
+			c->isfloating = True;
+			/* reuse tags field as mapped status */
+			c->tags = 1;
+			updatesizehints(c);
+			updatesystrayicongeom(c, wa.width, wa.height);
+			XAddToSaveSet(dpy, c->win);
+			XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask);
+			XReparentWindow(dpy, c->win, systray->win, 0, 0);
+			/* use parents background pixmap */
+			swa.background_pixmap = ParentRelative;
+			XChangeWindowAttributes(dpy, c->win, CWBackPixmap, &swa);
+			sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+			/* FIXME not sure if I have to send these events, too */
+			sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+			sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+			sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+			resizebarwin(selmon);
+			updatesystray();
+			setclientstate(c, NormalState);
+		}
+		return;
+	}
 	if(!c)
 		return;
 	if(cme->message_type == netatom[NetWMState]) {
@@ -595,7 +675,7 @@
 			dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
 			updatebars();
 			for(m = mons; m; m = m->next)
-				XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
+				resizebarwin(m);
 			focus(NULL);
 			arrange(NULL);
 		}
@@ -693,6 +773,11 @@
 
 	if((c = wintoclient(ev->window)))
 		unmanage(c, True);
+	else if((c = wintosystrayicon(ev->window))) {
+		removesystrayicon(c);
+		resizebarwin(selmon);
+		updatesystray();
+	}
 }
 
 void
@@ -748,6 +833,7 @@
 	XftColor *col;
 	Client *c;
 
+	resizebarwin(m);
 	for(c = m->clients; c; c = c->next) {
 		occ |= c->tags;
 		if(c->isurgent)
@@ -769,6 +855,9 @@
 	if(m == selmon) { /* status is only drawn on selected monitor */
 		dc.w = TEXTW(stext);
 		dc.x = m->ww - dc.w;
+		if(showsystray && m->status) {
+			dc.x -= getsystraywidth();
+		}
 		if(dc.x < x) {
 			dc.x = x;
 			dc.w = m->ww - x;
@@ -797,6 +886,7 @@
 
 	for(m = mons; m; m = m->next)
 		drawbar(m);
+	updatesystray();
 }
 
 void
@@ -944,10 +1034,17 @@
 	unsigned long dl;
 	unsigned char *p = NULL;
 	Atom da, atom = None;
+	/* FIXME getatomprop should return the number of items and a pointer to
+	 * the stored data instead of this workaround */
+	Atom req = XA_ATOM;
+	if(prop == xatom[XembedInfo])
+		req = xatom[XembedInfo];
 
-	if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM,
+	if(XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req,
 	                      &da, &di, &dl, &dl, &p) == Success && p) {
 		atom = *(Atom *)p;
+		if(da == xatom[XembedInfo] && dl == 2)
+			atom = ((Atom *)p)[1];
 		XFree(p);
 	}
 	return atom;
@@ -989,6 +1086,15 @@
 	return result;
 }
 
+unsigned int
+getsystraywidth() {
+	unsigned int w = 0;
+	Client *i;
+	if(showsystray)
+		for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ;
+	return w ? w + systrayspacing : 1;
+}
+
 Bool
 gettextprop(Window w, Atom atom, char *text, unsigned int size) {
 	char **list = NULL;
@@ -1101,7 +1207,7 @@
 killclient(const Arg *arg) {
 	if(!selmon->sel)
 		return;
-	if(!sendevent(selmon->sel, wmatom[WMDelete])) {
+	if(!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) {
 		XGrabServer(dpy);
 		XSetErrorHandler(xerrordummy);
 		XSetCloseDownMode(dpy, DestroyAll);
@@ -1185,6 +1291,12 @@
 maprequest(XEvent *e) {
 	static XWindowAttributes wa;
 	XMapRequestEvent *ev = &e->xmaprequest;
+	Client *i;
+	if((i = wintosystrayicon(ev->window))) {
+		sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION);
+		resizebarwin(selmon);
+		updatesystray();
+	}
 
 	if(!XGetWindowAttributes(dpy, ev->window, &wa))
 		return;
@@ -1298,6 +1410,16 @@
 	Window trans;
 	XPropertyEvent *ev = &e->xproperty;
 
+	if((c = wintosystrayicon(ev->window))) {
+		if(ev->atom == XA_WM_NORMAL_HINTS) {
+			updatesizehints(c);
+			updatesystrayicongeom(c, c->w, c->h);
+		}
+		else
+			updatesystrayiconstate(c, ev);
+			resizebarwin(selmon);
+			updatesystray();
+	}
 	if((ev->window == root) && (ev->atom == XA_WM_NAME))
 		updatestatus();
 	else if(ev->state == PropertyDelete)
@@ -1347,12 +1469,33 @@
 }
 
 void
+removesystrayicon(Client *i) {
+	Client **ii;
+
+	if(!showsystray || !i)
+		return;
+	for(ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next);
+	if(ii)
+		*ii = i->next;
+	free(i);
+}
+
+
+void
 resize(Client *c, int x, int y, int w, int h, Bool interact) {
 	if(applysizehints(c, &x, &y, &w, &h, interact))
 		resizeclient(c, x, y, w, h);
 }
 
 void
+resizebarwin(Monitor *m) {
+	unsigned int w = m->ww;
+	if(showsystray && m->status)
+		w -= getsystraywidth();
+	XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh);
+}
+
+void
 resizeclient(Client *c, int x, int y, int w, int h) {
 	XWindowChanges wc;
 
@@ -1418,6 +1561,18 @@
 }
 
 void
+resizerequest(XEvent *e) {
+	XResizeRequestEvent *ev = &e->xresizerequest;
+	Client *i;
+
+	if((i = wintosystrayicon(ev->window))) {
+		updatesystrayicongeom(i, ev->width, ev->height);
+		resizebarwin(selmon);
+		updatesystray();
+	}
+}
+
+void
 restack(Monitor *m) {
 	Client *c;
 	XEvent ev;
@@ -1501,25 +1656,35 @@
 }
 
 Bool
-sendevent(Client *c, Atom proto) {
+sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4) {
 	int n;
-	Atom *protocols;
+	Atom *protocols, mt;
 	Bool exists = False;
 	XEvent ev;
 
-	if(XGetWMProtocols(dpy, c->win, &protocols, &n)) {
-		while(!exists && n--)
-			exists = protocols[n] == proto;
-		XFree(protocols);
+	if(proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) {
+		mt = wmatom[WMProtocols];
+		if(XGetWMProtocols(dpy, w, &protocols, &n)) {
+			while(!exists && n--)
+				exists = protocols[n] == proto;
+			XFree(protocols);
+		}
+	}
+	else {
+		exists = True;
+		mt = proto;
 	}
 	if(exists) {
 		ev.type = ClientMessage;
-		ev.xclient.window = c->win;
-		ev.xclient.message_type = wmatom[WMProtocols];
+		ev.xclient.window = w;
+		ev.xclient.message_type = mt;
 		ev.xclient.format = 32;
-		ev.xclient.data.l[0] = proto;
-		ev.xclient.data.l[1] = CurrentTime;
-		XSendEvent(dpy, c->win, False, NoEventMask, &ev);
+		ev.xclient.data.l[0] = d0;
+		ev.xclient.data.l[1] = d1;
+		ev.xclient.data.l[2] = d2;
+		ev.xclient.data.l[3] = d3;
+		ev.xclient.data.l[4] = d4;
+		XSendEvent(dpy, w, False, mask, &ev);
 	}
 	return exists;
 }
@@ -1528,7 +1693,7 @@
 setfocus(Client *c) {
 	if(!c->neverfocus)
 		XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
-	sendevent(c, wmatom[WMTakeFocus]);
+	sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
 }
 
 void
@@ -1608,11 +1773,17 @@
 	wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
 	netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
 	netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
+	netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False);
+	netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False);
+	netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False);
 	netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
 	netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
 	netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
 	netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
 	netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
+	xatom[Manager] = XInternAtom(dpy, "MANAGER", False);
+	xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False);
+	xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False);
 	/* init cursors */
 	cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
 	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
@@ -1627,7 +1798,9 @@
 	dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen));
 	dc.gc = XCreateGC(dpy, root, 0, NULL);
 	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
-	/* init bars */
+    /* init system tray */
+    updatesystray();
+    /* init bars */
 	updatebars();
 	updatestatus();
 	/* EWMH support per view */
@@ -1731,7 +1904,18 @@
 togglebar(const Arg *arg) {
 	selmon->showbar = !selmon->showbar;
 	updatebarpos(selmon);
-	XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
+	resizebarwin(selmon);
+	if(showsystray) {
+		XWindowChanges wc;
+		if(!selmon->showbar)
+			wc.y = -bh;
+		else if(selmon->showbar) {
+			wc.y = 0;
+			if(!selmon->topbar)
+				wc.y = selmon->mh - bh;
+		}
+		XConfigureWindow(dpy, systray->win, CWY, &wc);
+	}
 	arrange(selmon);
 }
 
@@ -1827,18 +2011,28 @@
 		else
 			unmanage(c, False);
 	}
+	else if((c = wintosystrayicon(ev->window))) {
+		removesystrayicon(c);
+		resizebarwin(selmon);
+		updatesystray();
+	}
 }
 
 void
 updatebars(void) {
+	unsigned int w;
 	Monitor *m;
+
 	XSetWindowAttributes wa = {
 		.override_redirect = True,
 		.background_pixmap = ParentRelative,
 		.event_mask = ButtonPressMask|ExposureMask
 	};
 	for(m = mons; m; m = m->next) {
-		m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
+		w = m->ww;
+		if(showsystray && m == selmon)
+			w -= getsystraywidth();
+		m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen),
 		                          CopyFromParent, DefaultVisual(dpy, screen),
 		                          CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
 		XDefineCursor(dpy, m->barwin, cursor[CurNormal]);
@@ -2022,6 +2216,104 @@
 }
 
 void
+updatesystrayicongeom(Client *i, int w, int h) {
+	if(i) {
+		i->h = bh;
+		if(w == h)
+			i->w = bh;
+		else if(h == bh)
+			i->w = w;
+		else
+			i->w = (int) ((float)bh * ((float)w / (float)h));
+		applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False);
+		/* force icons into the systray dimenons if they don't want to */
+		if(i->h > bh) {
+			if(i->w == i->h)
+				i->w = bh;
+			else
+				i->w = (int) ((float)bh * ((float)i->w / (float)i->h));
+			i->h = bh;
+		}
+	}
+}
+
+void
+updatesystrayiconstate(Client *i, XPropertyEvent *ev) {
+	long flags;
+	int code = 0;
+
+	if(!showsystray || !i || ev->atom != xatom[XembedInfo] ||
+			!(flags = getatomprop(i, xatom[XembedInfo])))
+		return;
+
+	if(flags & XEMBED_MAPPED && !i->tags) {
+		i->tags = 1;
+		code = XEMBED_WINDOW_ACTIVATE;
+		XMapRaised(dpy, i->win);
+		setclientstate(i, NormalState);
+	}
+	else if(!(flags & XEMBED_MAPPED) && i->tags) {
+		i->tags = 0;
+		code = XEMBED_WINDOW_DEACTIVATE;
+		XUnmapWindow(dpy, i->win);
+		setclientstate(i, WithdrawnState);
+	}
+	else
+		return;
+	sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0,
+			systray->win, XEMBED_EMBEDDED_VERSION);
+}
+
+void
+updatesystray(void) {
+	XSetWindowAttributes wa;
+	Client *i;
+	unsigned int x = selmon->mx + selmon->mw;
+	unsigned int w = 1;
+
+	if(!showsystray)
+		return;
+	if(!systray) {
+		/* init systray */
+		if(!(systray = (Systray *)calloc(1, sizeof(Systray))))
+			die("fatal: could not malloc() %u bytes\n", sizeof(Systray));
+		systray->win = XCreateSimpleWindow(dpy, root, x, selmon->by, w, bh, 0, 0, dc.sel[ColBG].pixel);
+		wa.event_mask        = ButtonPressMask | ExposureMask;
+		wa.override_redirect = True;
+		wa.background_pixmap = ParentRelative;
+		wa.background_pixel  = dc.norm[ColBG].pixel;
+		XSelectInput(dpy, systray->win, SubstructureNotifyMask);
+		XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32,
+				PropModeReplace, (unsigned char *)&systrayorientation, 1);
+		XChangeWindowAttributes(dpy, systray->win, CWEventMask | CWOverrideRedirect | CWBackPixel, &wa);
+		XMapRaised(dpy, systray->win);
+		XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime);
+		if(XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) {
+			sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0);
+			XSync(dpy, False);
+		}
+		else {
+			fprintf(stderr, "dwm: unable to obtain system tray.\n");
+			free(systray);
+			systray = NULL;
+			return;
+		}
+	}
+	for(w = 0, i = systray->icons; i; i = i->next) {
+		XMapRaised(dpy, i->win);
+		w += systrayspacing;
+		XMoveResizeWindow(dpy, i->win, (i->x = w), 0, i->w, i->h);
+		w += i->w;
+		if(i->mon != selmon)
+			i->mon = selmon;
+	}
+	w = w ? w + systrayspacing : 1;
+ 	x -= w;
+	XMoveResizeWindow(dpy, systray->win, x, selmon->by, w, bh);
+	XSync(dpy, False);
+}
+
+void
 updatewindowtype(Client *c) {
 	Atom state = getatomprop(c, netatom[NetWMState]);
 	Atom wtype = getatomprop(c, netatom[NetWMWindowType]);
@@ -2106,6 +2398,16 @@
 	return selmon;
 }
 
+Client *
+wintosystrayicon(Window w) {
+	Client *i = NULL;
+
+	if(!showsystray || !w)
+		return i;
+	for(i = systray->icons; i && i->win != w; i = i->next) ;
+	return i;
+}
+
 /* There's no way to check accesses to destroyed windows, thus those cases are
  * ignored (especially on UnmapNotify's).  Other types of errors call Xlibs
  * default error handler, which may call exit.  */

Last edited by Unia (2012-12-15 00:15:53)


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#1038 2012-12-21 03:36:51

hazeldf
Member
Registered: 2012-06-10
Posts: 10

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

Hello friends (newbie in dwm)

I always got -Wunused-function when running 'makepkg -efi' command.. hmm
What's that? hmm

Offline

#1039 2012-12-21 03:52:57

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

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

Do you get that with the default config.h or with a custom one?  If with a custom one I suspect you removed some of the default bindings which leaves some of the functions unused.  Hence the unused function warning.

This is just a warning, and it should still compile just fine.  If it doesn't you can check the Makefile for the "-pedantic" or "-Werror" flags and remove them.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#1040 2012-12-21 06:54:12

hazeldf
Member
Registered: 2012-06-10
Posts: 10

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

Trilby wrote:

Do you get that with the default config.h or with a custom one?  If with a custom one I suspect you removed some of the default bindings which leaves some of the functions unused.  Hence the unused function warning.

This is just a warning, and it should still compile just fine.  If it doesn't you can check the Makefile for the "-pedantic" or "-Werror" flags and remove them.

I use config.h file that already in /var/abs/community/dwm  hmm
I'll try that..

also.. how to change "dwm-6" text ?

Offline

#1041 2012-12-21 08:57:39

andjeng
Member
From: Indonesia
Registered: 2012-08-30
Posts: 148

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

hazeldf wrote:
Trilby wrote:

Do you get that with the default config.h or with a custom one?  If with a custom one I suspect you removed some of the default bindings which leaves some of the functions unused.  Hence the unused function warning.

This is just a warning, and it should still compile just fine.  If it doesn't you can check the Makefile for the "-pedantic" or "-Werror" flags and remove them.

I use config.h file that already in /var/abs/community/dwm  hmm
I'll try that..

also.. how to change "dwm-6" text ?

zel zel zel, how could you do that?
do you know who am i?

=====

may i ask somethin' about the recommended way to install dwm?
which you prefer, pacman way or manual?


just looking around. wink

Offline

#1042 2012-12-21 09:21:01

Army
Member
Registered: 2007-12-07
Posts: 1,784

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

hazeldf wrote:

also.. how to change "dwm-6" text ?

Depends on what you want to change this to. I for example replace it with conky like this.

Offline

#1043 2012-12-21 09:23:34

Army
Member
Registered: 2007-12-07
Posts: 1,784

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

andjeng wrote:

zel zel zel, how could you do that?
do you know who am i?

??

andjeng wrote:

may i ask somethin' about the recommended way to install dwm?
which you prefer, pacman way or manual?

Dwm should always be manually compiled. That's how it's designed. I still wonder why we have it in the repos, this just doesn't make much sense.

Last edited by Army (2012-12-21 11:35:41)

Offline

#1044 2012-12-21 10:20:29

hazeldf
Member
Registered: 2012-06-10
Posts: 10

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

Army wrote:
hazeldf wrote:

also.. how to change "dwm-6" text ?

Depends on what you want to change this to. I for example replace it with conky like this.

thank you sir.. that's what I need big_smile

Offline

#1045 2012-12-22 10:16:00

hazeldf
Member
Registered: 2012-06-10
Posts: 10

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

can you combine bstack patch and pertag patch ?

Offline

#1046 2012-12-22 11:53:53

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

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

hazeldf wrote:

can you combine bstack patch and pertag patch ?

I have one: https://github.com/Unia/DWM-XFT/blob/ma … rtag2.diff

Last edited by Unia (2012-12-22 11:54:46)


If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#1047 2012-12-22 15:05:24

Unia
Member
From: Stockholm, Sweden
Registered: 2010-03-30
Posts: 2,486
Website

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

Hello friends,

I have a question about the push patch. I only want to be able to move clients in the stack, I don't want them to move from master to stack or from stack to master. I have already removed some lines so it doesn't cycle anymore, but with pushup I can still move a client from stack to master and with pushdown I can still move master to stack.

How can I modify what I currently have, so I can only move windows in the stack?

static Client *
prevtiled(Client *c) {
    Client *p, *r;

    for(p = selmon->clients, r = NULL; p && p != c; p = p->next)
        if(!p->isfloating && ISVISIBLE(p))
            r = p;
    return r;
}

static void
pushup(const Arg *arg) {
    Client *sel = selmon->sel;
    Client *c;

    if(!sel || sel->isfloating)
        return;
    if((c = prevtiled(sel))) {
        /* attach before c */
        detach(sel);
        sel->next = c;
        if(selmon->clients == c)
        selmon->clients = sel;
        else {
            for(c = selmon->clients; c->next != sel->next; c = c->next);
            c->next = sel;
        }
    }
    focus(sel);
    arrange(selmon);
}

static void
pushdown(const Arg *arg) {
    Client *sel = selmon->sel;
    Client *c;

    if(!sel || sel->isfloating)
        return;
    if((c = nexttiled(sel->next))) {
        /* attach after c */
        detach(sel);
        sel->next = c->next;
        c->next = sel;
    }
    focus(sel);
    arrange(selmon);
}

If you can't sit by a cozy fire with your code in hand enjoying its simplicity and clarity, it needs more work. --Carlos Torres

Offline

#1048 2012-12-22 19:43:12

ANOKNUSA
Member
Registered: 2010-10-22
Posts: 2,141

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

Army wrote:
andjeng wrote:

zel zel zel, how could you do that?
do you know who am i?

??

andjeng wrote:

may i ask somethin' about the recommended way to install dwm?
which you prefer, pacman way or manual?

Dwm should always be manually compiled. That's how it's designed. I still wonder why we have it in the repos, this just doesn't make much sense.


One can alter the PKGBUILD such that it grabs the source, grabs and applies patches, pauses for any manual intervention and then installs DWM in /usr/bin.

Offline

#1049 2012-12-23 08:59:00

Army
Member
Registered: 2007-12-07
Posts: 1,784

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

Sure, but a package like this could be provided in the AUR, which would be a lot better imo.

Offline

#1050 2012-12-23 12:04:59

hazeldf
Member
Registered: 2012-06-10
Posts: 10

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

Unia wrote:
hazeldf wrote:

can you combine bstack patch and pertag patch ?

I have one: https://github.com/Unia/DWM-XFT/blob/ma … rtag2.diff

hi Unia..
I'm always got fail when try to compile that patch
one error that I have seen : "error on line bla..bla..bla" that is about x += TEXTW(tags i.name); hmm

Offline

Board footer

Powered by FluxBB