[dwm] Re: Quick patch for multihead

From: Guillaume Quintin <coincoin169g_AT_gmail.com>
Date: Sun, 29 Mar 2009 23:02:26 +0200

QUINTIN Guillaume wrote:
> Hello,
>
> As I have no time to code, I have written this patch in 30 minutes. It's a
> patch to have a multi-head support "like" E17, I am not at home, so I don't
> know if it works correctly ! The only thing I know for sure is that it
> compiles without error on a PC which is not mine. Maybe it won't work at
> all. I won't be in front of my PC until tonight so can you (if you have
> nothing else to do) test it ?
>
> (I have set MODKEY to Mod4Mask)
>
> MODKEY + AltKey + Number = Place the select client on the screen number
> Number, if a client is already on the screen, it is replaced.
> MODKEY + Enter = normal behavior but when the window is on another screen it
> moves it in the main screen (where the bar is)
>
> Thanks
>
>

Please forget about my last post, the patch does not work, it does not
even compile ...

I just came up with this little patch that store informations about
other monitors (than the one on which is the mouse) and a little
function that moves the selected client to the screen number arg->i.

This one is working and is very useful for me.

-- 
Kind regards
Guillaume Quintin

--- dwm.old.c 2009-02-08 13:10:49.000000000 +0100
+++ dwm.c 2009-03-29 22:47:59.000000000 +0200
@@ -127,6 +127,11 @@
         Bool isfloating;
 } Rule;
 
+/* struct to store other monitors info */
+typedef struct {
+ int wx,wy,ww,wh;
+} Monitor;
+
 /* function declarations */
 static void adjustborder(Client *c, unsigned int bw);
 static void applyrules(Client *c);
@@ -203,6 +208,7 @@
 static int xerrordummy(Display *dpy, XErrorEvent *ee);
 static int xerrorstart(Display *dpy, XErrorEvent *ee);
 static void zoom(const Arg *arg);
+void win2mon(const Arg *);
 
 /* variables */
 static char stext[256];
@@ -210,6 +216,7 @@
 static int sx, sy, sw, sh; /* X display screen geometry x, y, width, height */
 static int by, bh, blw; /* bar geometry y, height and layout symbol width */
 static int wx, wy, ww, wh; /* window area geometry x, y, width, height, bar excluded */
+Monitor *monitors;int nb_mon; /* the other monitors */
 static unsigned int seltags = 0, sellt = 0;
 static int (*xerrorxlib)(Display *, XErrorEvent *);
 static unsigned int numlockmask = 0;
@@ -1524,21 +1531,41 @@
         int n, i = 0;
         XineramaScreenInfo *info = NULL;
 
+ if ( monitors ) { free(monitors); }
+
         /* window area geometry */
- if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) {
- if(n > 1) {
- int di, x, y;
- unsigned int dui;
- Window dummy;
- if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui))
- for(i = 0; i < n; i++)
- if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))
- break;
+ if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n)))
+ {
+ nb_mon = n - 1;
+ if ( n > 1 )
+ {
+ monitors = malloc(nb_mon * sizeof(Monitor));
+ if ( !monitors ) { die("Not enough memory for monitors' informations."); }
+ }
+ int di, x, y, id = 0;
+ unsigned int dui;
+ Window dummy;
+ if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui))
+ {
+ for(i = 0; i < n; i++)
+ {
+ if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))
+ {
+ wx = info[i].x_org;
+ wy = showbar && topbar ? info[i].y_org + bh : info[i].y_org;
+ ww = info[i].width;
+ wh = showbar ? info[i].height - bh : info[i].height;
+ }
+ else
+ {
+ monitors[id].wx = info[i].x_org;
+ monitors[id].wy = info[i].y_org;
+ monitors[id].ww = info[i].width;
+ monitors[id].wh = info[i].height;
+ id++;
+ }
+ }
                 }
- wx = info[i].x_org;
- wy = showbar && topbar ? info[i].y_org + bh : info[i].y_org;
- ww = info[i].width;
- wh = showbar ? info[i].height - bh : info[i].height;
                 XFree(info);
         }
         else
@@ -1705,6 +1732,16 @@
         arrange();
 }
 
+void win2mon(const Arg *arg)
+{
+ if ( arg->i > nb_mon || !sel ) { return; }
+ Monitor *m = &monitors[arg->i];
+ sel->tags = ~0;
+ sel->isfloating = 1;
+ resize(sel,m->wx,m->wy,m->ww - 2 * sel->bw,m->wh - 2 * sel->bw,1);
+ arrange();
+}
+
 int
 main(int argc, char *argv[]) {
         if(argc == 2 && !strcmp("-v", argv[1]))

/* See LICENSE file for copyright and license details. */

/* appearance */
static const char font[] = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*";
static const char normbordercolor[] = "#cccccc";
static const char normbgcolor[] = "#cccccc";
static const char normfgcolor[] = "#000000";
static const char selbordercolor[] = "#0066ff";
static const char selbgcolor[] = "#0066ff";
static const char selfgcolor[] = "#ffffff";
static unsigned int borderpx = 1; /* border pixel of windows */
static unsigned int snap = 32; /* snap pixel */
static Bool showbar = True; /* False means no bar */
static Bool topbar = True; /* False means bottom bar */
static Bool usegrab = False; /* True means grabbing the X server
                                                   during mouse-based resizals */

/* tagging */
static const char tags[][MAXTAGLEN] = { "1.terms", "2.e-mail", "3.amule", "4.im", "5.web", "6.devel", "7.misc", "8.misc", "9.misc" };
static unsigned int tagset[] = {1, 1}; /* after start, first tag is selected */

static Rule rules[] = {
        /* class instance title tags mask isfloating */
        { "MPlayer", NULL, NULL, 0, True },
};

/* layout(s) */
static float mfact = 0.55; /* factor of master area size [0.05..0.95] */
static Bool resizehints = True; /* False means respect size hints in tiled resizals */

static Layout layouts[] = {
        /* symbol arrange function */
        { "[]=", tile }, /* first entry is default */
        { "><>", NULL }, /* no layout function means floating behavior */
        { "[M]", monocle },
};

/* key definitions */
#define MODKEY Mod4Mask
#define TAGKEYS(KEY,TAG) \
        { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
        { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
        { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
        { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },

/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }

/* commands */
static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
static const char *termcmd[] = { "uxterm", NULL };

static Key keys[] = {
        /* modifier key function argument */
        { MODKEY, XK_p, spawn, {.v = dmenucmd } },
        { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
        { MODKEY, XK_b, togglebar, {0} },
        { MODKEY, XK_j, focusstack, {.i = +1 } },
        { MODKEY, XK_k, focusstack, {.i = -1 } },
        { MODKEY, XK_h, setmfact, {.f = -0.05} },
        { MODKEY, XK_l, setmfact, {.f = +0.05} },
        { MODKEY, XK_Return, zoom, {0} },
        { MODKEY, XK_Tab, view, {0} },
        { MODKEY|ShiftMask, XK_c, killclient, {0} },
        { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
        { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
        { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
        { MODKEY, XK_space, setlayout, {0} },
        { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
        { MODKEY, XK_agrave, view, {.ui = ~0 } },
        { MODKEY|ShiftMask, XK_agrave, tag, {.ui = ~0 } },
        TAGKEYS( XK_ampersand, 0)
        TAGKEYS( XK_eacute, 1)
        TAGKEYS( XK_quotedbl, 2)
        TAGKEYS( XK_apostrophe, 3)
        TAGKEYS( XK_parenleft, 4)
        TAGKEYS( XK_minus, 5)
        TAGKEYS( XK_egrave, 6)
        TAGKEYS( XK_underscore, 7)
        TAGKEYS( XK_agrave, 8)
        { MODKEY|ShiftMask, XK_q, quit, {0} },
        { MODKEY|Mod1Mask, XK_ampersand, win2mon, { .i = 0 } },
        { MODKEY|Mod1Mask, XK_eacute, win2mon, { .i = 1 } },
        { MODKEY|Mod1Mask, XK_quotedbl, win2mon, { .i = 2 } },
        { MODKEY|Mod1Mask, XK_apostrophe, win2mon, { .i = 3 } },
        { MODKEY|Mod1Mask, XK_parenleft, win2mon, { .i = 4 } },
        { MODKEY|Mod1Mask, XK_minus, win2mon, { .i = 5 } },
        { MODKEY|Mod1Mask, XK_egrave, win2mon, { .i = 6 } },
        { MODKEY|Mod1Mask, XK_underscore, win2mon, { .i = 7 } },
        { MODKEY|Mod1Mask, XK_ccedilla, win2mon, { .i = 8 } },
};

/* button definitions */
/* click can be a tag number (starting at 0),
 * ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
        /* click event mask button function argument */
        { ClkLtSymbol, 0, Button1, setlayout, {0} },
        { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
        { ClkWinTitle, 0, Button2, zoom, {0} },
        { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
        { ClkClientWin, MODKEY, Button1, movemouse, {0} },
        { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
        { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
        { ClkTagBar, 0, Button1, view, {0} },
        { ClkTagBar, 0, Button3, toggleview, {0} },
        { ClkTagBar, MODKEY, Button1, tag, {0} },
        { ClkTagBar, MODKEY, Button3, toggletag, {0} },
};
Received on Sun Mar 29 2009 - 21:02:26 UTC

This archive was generated by hypermail 2.2.0 : Sun Mar 29 2009 - 22:12:05 UTC