You are not logged in.

#151 2009-11-12 02:43:15

Aedit
Member
Registered: 2009-10-29
Posts: 138

Re: Scrotwm / Spectrwm

@skanky: nice script, thanks!

I have updated the script in the wiki to include essid and memory usage as you did.
I also added battery/AC information, pulling the info from /proc so there is no dependency
on acpi and more control over formatting.

Everyone post your scripts please!

Offline

#152 2009-11-12 03:04:48

yvonney
Member
Registered: 2008-06-11
Posts: 671

Re: Scrotwm / Spectrwm

fabulous! thank you all.

Offline

#153 2009-11-12 07:21:59

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: Scrotwm / Spectrwm

Aedit wrote:

@skanky: nice script, thanks!

I have updated the script in the wiki to include essid and memory usage as you did.
I also added battery/AC information, pulling the info from /proc so there is no dependency
on acpi and more control over formatting.

Everyone post your scripts please!

That's good, thanks. I've found that acpi sometimes returns nothing. I can force it to return something in those cases by doing acpi -p which makes it go to /proc, but in that case, I'm not sure why it normally works without -p. So that's incentive enough to go directly to /proc myself.


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#154 2009-12-19 17:37:16

virus_found
Member
From: Moscow
Registered: 2009-05-22
Posts: 51
Website

Re: Scrotwm / Spectrwm

Gentooer wrote:

I've decided to just get rid of the status bar (I use xosd for any notifications), so I almost have fullscreen.  I don't see any way to disable the window border though.  Is it possible to just disable it for the fullscreen layout, and keep it for veritcal/horizontal layout?  I suppose I could just turn the border black for active windows, but then I'm missing a pixel on each side.

I usually run my desktop with a 800x600 LED projector, so I need every pixel I can get! smile

If you don't mind, I second this (very important) question.

EDIT>
Btw, #scrotwm on Freenode awaits you smile

Last edited by virus_found (2009-12-20 17:11:25)

Offline

#155 2010-01-10 13:47:03

Aedit
Member
Registered: 2009-10-29
Posts: 138

Re: Scrotwm / Spectrwm

Gentooer wrote:

I've decided to just get rid of the status bar (I use xosd for any notifications), so I almost have fullscreen.  I don't see any way to disable the window border though.  Is it possible to just disable it for the fullscreen layout, and keep it for veritcal/horizontal layout?  I suppose I could just turn the border black for active windows, but then I'm missing a pixel on each side.

I usually run my desktop with a 800x600 LED projector, so I need every pixel I can get! smile

Here's a patch I wrote to get true fullscreen without the 1 pixel border. The border width is now set to zero whenever there is only one window displayed and the status bar is hidden (press Meta+b). Otherwise the behaviour is unchanged. This works in all three layouts.

--- scrotwm.c   2010-01-10 18:02:10.823809086 +0000
+++ scrotwm.c.new       2010-01-10 18:01:41.843805061 +0000
@@ -2079,7 +2079,12 @@
                        win_g.y += last_h + 2;

                bzero(&wc, sizeof wc);
-               wc.border_width = 1;
+               if (bar_enabled == 0 && winno == 1){
+                       wc.border_width = 0;
+                       win_g.w += 2;
+                       win_g.h += 2;
+               } else
+                       wc.border_width = 1;
                reconfigure = 0;
                if (rot) {
                        if (win->g.x != win_g.y || win->g.y != win_g.x ||
@@ -2251,11 +2256,17 @@
                if (win->g.x != gg.x || win->g.y != gg.y || win->g.w != gg.w ||
                    win->g.h != gg.h) {
                        bzero(&wc, sizeof wc);
-                       wc.border_width = 1;
                        win->g.x = wc.x = gg.x;
                        win->g.y = wc.y = gg.y;
-                       win->g.w = wc.width = gg.w;
-                       win->g.h = wc.height = gg.h;
+                       if (bar_enabled){
+                               wc.border_width = 1;
+                               win->g.w = wc.width = gg.w;
+                               win->g.h = wc.height = gg.h;
+                       } else {
+                               wc.border_width = 0;
+                               win->g.w = wc.width = gg.w + 2;
+                               win->g.h = wc.height = gg.h + 2;
+                       }
                        mask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
                        XConfigureWindow(display, win->id, mask, &wc);
                        configreq_win(win);

Enjoy the extra 2796 pixels.
Edit:updated patch

Last edited by Aedit (2010-01-10 18:19:33)

Offline

#156 2010-01-10 14:11:26

virus_found
Member
From: Moscow
Registered: 2009-05-22
Posts: 51
Website

Re: Scrotwm / Spectrwm

Thank you very much for this! This should be definitely pushed to cvs.

Offline

#157 2010-01-11 18:23:36

Aedit
Member
Registered: 2009-10-29
Posts: 138

Re: Scrotwm / Spectrwm

virus_found wrote:

Thank you very much for this! This should be definitely pushed to cvs.

Hope so. Here's another one:

Currently scrotwm doesn't compile if SWM_DEBUG is defined because of a missing variable in (what's left of) focusevent. The following patch is needed:


--- scrotwm.c   2010-01-11 17:27:46.000000000 +0000
+++ scrotwm.c.new       2010-01-11 17:28:02.000000000 +0000
@@ -98,7 +98,7 @@
 #endif
 #endif
 
-/* #define SWM_DEBUG */
+#define SWM_DEBUG
 #ifdef SWM_DEBUG
 #define DPRINTF(x...)          do { if (swm_debug) fprintf(stderr, x); } while (0)
 #define DNPRINTF(n,x...)       do { if (swm_debug & n) fprintf(stderr, x); } while (0)
@@ -4097,10 +4097,6 @@
 void
 focusevent(XEvent *e)
 {
-       DNPRINTF(SWM_D_EVENT, "focusevent: %s window: %lu mode %d detail %d\n",
-           ev->type == FocusIn ? "entering" : "leaving",
-           ev->window, ev->mode, ev->detail);
-#if 0
        struct ws_win           *win;
        u_int32_t               mode_detail;
        XFocusChangeEvent       *ev = &e->xfocus;
@@ -4108,7 +4104,7 @@
        DNPRINTF(SWM_D_EVENT, "focusevent: %s window: %lu mode %d detail %d\n",
            ev->type == FocusIn ? "entering" : "leaving",
            ev->window, ev->mode, ev->detail);
-
+#if 0
        if (last_focus_event == ev->type) {
                DNPRINTF(SWM_D_FOCUS, "ignoring focusevent: bad ordering\n");
                return;

Offline

#158 2010-01-11 18:29:55

JuseBox
Member
Registered: 2009-11-27
Posts: 260

Re: Scrotwm / Spectrwm

Inxsible wrote:

The first time I read it....I read scrotum wink HAHAHHAHA

HAHA big_smile


Linux ArchLinux 3.2.8-1-ARCH
#1 SMP PREEMPT Mon Feb 27 21:51:46 CET 2012 x86_64 AMD FX(tm)-8120 Eight-Core Processor AuthenticAMD GNU/Linux
8192MB DDR3 1300MHz | Asus m5a97 | GeForce GTX 550 Ti | 120 GB SSD

Offline

#159 2010-01-12 00:22:06

Aedit
Member
Registered: 2009-10-29
Posts: 138

Re: Scrotwm / Spectrwm

OK here's a third patch, and this one is a BUGFIX.

Bug description: I found that using 2-monitor xinerama, if I define two regions in the config file for the two monitors, upon startup the regions show "1:2" and "2:3", i.e. regions 1 and 2 are showing workspaces 2 and 3 respectively (not the expected "1:1", "2:2"). Selecting workspaces with Meta+1,2,3...0 is messed up, sometimes showing the _wrong_ workspaces where the desired workspace has no windows.

A pointer in workspace 1 is still pointing to the total default region which is removed from the region list after the custom subregions are created.

Anyway this fixes the problem:

--- scrotwm.c   2010-01-11 23:12:22.089411165 +0000
+++ scrotwm.c.new       2010-01-11 23:42:44.792562402 +0000
@@ -4311,6 +4311,8 @@
                    (X(r) + WIDTH(r)) > x &&
                    Y(r) < (y + h) &&
                    (Y(r) + HEIGHT(r)) > y) {
+                       /* ensure ws doesn't point to dead region */
+                       r->ws->r = NULL;
                        XDestroyWindow(display, r->bar_window);
                        TAILQ_REMOVE(&s->rl, r, entry);
                        TAILQ_INSERT_TAIL(&s->orl, r, entry);

Offline

#160 2010-01-12 00:58:05

virus_found
Member
From: Moscow
Registered: 2009-05-22
Posts: 51
Website

Re: Scrotwm / Spectrwm

There have recently been some commits to the cvs, and all your patches fail to apply, unfortunately.

Offline

#161 2010-01-12 03:03:18

Aedit
Member
Registered: 2009-10-29
Posts: 138

Re: Scrotwm / Spectrwm

virus_found wrote:

There have recently been some commits to the cvs, and all your patches fail to apply, unfortunately.

I did use the latest CVS before posting and they still apply for me. The whitespace was probably mangled (tabs->spaces). They are small patches so it's probably quickest to just edit scrotwm.c by hand.

Last edited by Aedit (2010-01-12 04:04:57)

Offline

#162 2010-01-12 03:33:01

Aedit
Member
Registered: 2009-10-29
Posts: 138

Re: Scrotwm / Spectrwm

Here is patch number 4. Another BUGFIX, actually two.

Bug1: If I press Meta+Shift+Right/Left to focus on the next/previous region nothing happens. This is because it checks for ScreenCount>1 or outputs>1. On my 2-screen xinerama box (nvidia driver) ScreenCount=1 and outputs=0 (as always if there is no xrandr_support). But anyway what matters here is _regions_ not screens. Remove the check and you can even define multiple regions on a single physical screen and navigate between them (I checked).

Bug2: The mouse positioning calculation has an operator precendence error -- in some geometries the mouse will be outside the desired region.

--- scrotwm.c   2010-01-11 23:12:22.089411165 +0000
+++ scrotwm.c.new       2010-01-12 02:56:33.531399676 +0000
@@ -1579,10 +1579,6 @@
        union arg               a;
        int                     i, x, y;
 
-       /* do nothing if we don't have more than one screen */
-       if (!(ScreenCount(display) > 1 || outputs > 1))
-               return;
-
        i = r->s->idx;
        switch (args->id) {
        case SWM_ARG_ID_CYCLESC_UP:
@@ -1603,7 +1599,7 @@
 
        /* move mouse to region */
        x = rr->g.x + 1;
-       y = rr->g.y + 1 + bar_enabled ? bar_height : 0;
+       y = rr->g.y + 1 + (bar_enabled ? bar_height : 0);
        XWarpPointer(display, None, rr->s[i].root, 0, 0, 0, 0, x, y);
 
        a.id = SWM_ARG_ID_FOCUSCUR;

Offline

#163 2010-01-12 04:35:04

Aedit
Member
Registered: 2009-10-29
Posts: 138

Re: Scrotwm / Spectrwm

Both the issues in the last patch appear again in the restart section of main().

So here is patch 5 (BUGFIX).

I guess the multiscreen check could be improved so it works in all cases but it doesn't seem to do any harm to just "home" the pointer when restarting on single screens too.

--- scrotwm.c   2010-01-11 23:12:22.089411165 +0000
+++ scrotwm.c.new       2010-01-12 02:56:38.947754647 +0000
@@ -4699,11 +4699,10 @@
                                winfocus = NULL;
                                continue;
                        }
-                       /* move pointer to first screen if multi screen */
-                       if (ScreenCount(display) > 1 || outputs > 1)
-                               XWarpPointer(display, None, rr->s[0].root,
-                                   0, 0, 0, 0, rr->g.x,
-                                   rr->g.y + bar_enabled ? bar_height : 0);
+                       /* move pointer to first screen */
+                       XWarpPointer(display, None, rr->s[0].root,
+                           0, 0, 0, 0, rr->g.x,
+                           rr->g.y + (bar_enabled ? bar_height : 0));
 
                        a.id = SWM_ARG_ID_FOCUSCUR;
                        focus(rr, &a);

Offline

#164 2010-01-12 13:20:31

Aedit
Member
Registered: 2009-10-29
Posts: 138

Re: Scrotwm / Spectrwm

Aedit wrote:

I did use the latest CVS before posting and they still apply for me. The whitespace was probably mangled (tabs->spaces). They are small patches so it's probably quickest to just edit scrotwm.c by hand.

Or you could try patch --ignore-whitespace if you dare.

Edit: yes, that works.

Last edited by Aedit (2010-01-21 18:18:22)

Offline

#165 2010-01-14 13:52:31

marco_p
Member
Registered: 2009-02-09
Posts: 81

Re: Scrotwm / Spectrwm

You really should email me these.  I just happened to run into these patches.  I currently don't have time to reply to them individually but I'll look at them shortly.

Offline

#166 2010-01-14 14:24:15

Aedit
Member
Registered: 2009-10-29
Posts: 138

Re: Scrotwm / Spectrwm

Yeah I know -- I was about to email them but fortunately you have already found them. I posted the first one here because Gentooer and virus_found asked about that feature here, and one thing led to another.

Thanks for looking at them.

Offline

#167 2010-01-14 20:52:42

marco_p
Member
Registered: 2009-02-09
Posts: 81

Re: Scrotwm / Spectrwm

Please mail them anyway :-)

Make sure they are run with diff -uNp

Offline

#168 2010-01-15 17:04:34

Aedit
Member
Registered: 2009-10-29
Posts: 138

Re: Scrotwm / Spectrwm

Aedit wrote:

To make it look better it would be nice if scrotwm would accept colour text escape codes and UTF-8 charaters from baraction.sh.

I wrote the patch below to parse colour escape codes so that the text in the status bar can be displayed in multiple colours. I used an inline tag format like dzen2 to change the foreground color. The background and border colors are set in the config file as before. Note you can use both names and rgb numbers.

For example:

This is ^fg(hot pink)hot pink text,^fg(#ffd700) this is gold,^fg(rgb:7f/ff/d4) and this is aquamarine.

So now just set up baraction.sh to output text strings including color tags, for example to represent battery status, temperature, wifi signal strength and the like. Each character may be a different 24-bit colour, changing every 1s. Looking forward to seeing your screenshots!

Here it is, patch number 6:

--- scrotwm.c    2010-01-15 10:55:46.582950350 +0000
+++ scrotwm.colorbar.c    2010-01-15 10:54:36.042941634 +0000
@@ -698,13 +698,63 @@ socket_setnonblock(int fd)
         err(1, "fcntl F_SETFL");
 }
 
+#define MAX_COLOR_LEN 20
+#define MAX_SECT_LEN 512
 void
 bar_print(struct swm_region *r, char *s)
 {
+/* print s in the bar, parsing and applying any inline color tags */
+/* formats include: ^fg(rgb:12/fa/43), ^fg(red), ^fg(#12fa43) */
+        int is = 0, ig = 0, k, ic = 0, iu = 0;
+    int xpos = 4;             /* starting x position */
+        const char *g = "^fg(";   /* the foregroud color tag */
+        char u[MAX_SECT_LEN];     /* section of text between tags */
+        char cname[MAX_COLOR_LEN];
+    unsigned long color;
+
     XClearWindow(display, r->bar_window);
     XSetForeground(display, bar_gc, r->s->c[SWM_S_COLOR_BAR_FONT].color);
-    XDrawString(display, r->bar_window, bar_gc, 4, bar_fs->ascent, s,
-        strlen(s));
+
+        while (s[is] != '\0' && iu < (MAX_SECT_LEN-1)) {
+                if ( s[is] != g[ig] ) {
+                        if (ig != 0) {
+                /* partial tag not full one, catch up */
+                                for (k = 0; k < ig; k++) {
+                                        u[iu++] = s[is-ig+k];
+                                }
+                                ig = 0; //reset tag search
+                        }
+                        u[iu++]=s[is++];
+                } else {
+                        if (ig == strlen(g)-1) {
+                                /* found full tag: print previous section */
+                                u[iu] = '\0';
+                XDrawString(display, r->bar_window, bar_gc, xpos, bar_fs->ascent, u, strlen(u));
+                xpos += XTextWidth(bar_fs, u, strlen(u));
+                                is++;
+                                /* read and set new colour */
+                                for (ic = 0; ic < (MAX_COLOR_LEN-1) && s[is] != ')'; is++, ic++) {
+                                        cname[ic] = s[is];
+                                }
+                                cname[ic] = '\0';
+                if (s[is] == ')') {
+                    color = name_to_color(cname);
+                    XSetForeground(display, bar_gc, color);
+                }
+                                /* reset tag search */
+                                is += 1;
+                                iu = 0;
+                                ig = 0;
+                        } else {
+                                /* partial tag, look for next tag char */
+                                is++;
+                                ig++;
+                        }
+                }
+        }
+        /* final part of the string */
+        u[iu] = '\0';
+    XDrawString(display, r->bar_window, bar_gc, xpos, bar_fs->ascent, u, strlen(u));
 }
 
 void

@marco_p: I have sent the patches by email.

Last edited by Aedit (2010-01-15 17:39:35)

Offline

#169 2010-01-18 03:01:21

marco_p
Member
Registered: 2009-02-09
Posts: 81

Re: Scrotwm / Spectrwm

i'll look at these as soon as i get some time.  my other projects are keeping me quite busy right now but hang in there.

Offline

#170 2010-01-21 16:33:25

Aedit
Member
Registered: 2009-10-29
Posts: 138

Re: Scrotwm / Spectrwm

@marco_p: OK, I hope you have some time soon.

Anyway I have written another patch (and 2 small ones) to fix a number of problems to do with floating windows.

PATCH 6.5: increased SWM_BAR_MAX to 1024 because with color tags it is easy to exceed 256 characters.

PATCH 7:
* I implemented retention of the geometries of floating windows (and transient where applicable). This keeps them in the same relative positions after all of the following:
(i) floating toggles (Mod+t)
(ii) layout changes, including after maximized layout
(iii) switching workspaces to different monitors (any number, and may be of different sizes)
* Cleaner click to float (immediate restack).
* Raise floating window on move or resize (i.e. Mod+leftclick or Mod+rightclick).
* Allow moving floating windows partially offscreen.
* Prevent unwanted operations during maximized layout (floating toggles, moves, resizes).
* Fixed some 1 pixel errors like the sqrt(2) pixel jump southeast on move.

I checked all this with 2-head xinerama (nvidia driver, differently sized monitors) and single monitor Intel. Things are working well on these systems now.

PATCH 8: rename some defines I added previously


Here is PATCH 7:

--- scrotwm.c    2010-01-15 10:55:46.582950350 +0000
+++ scrotwm.float.c    2010-01-21 09:10:15.908224693 +0000
@@ -241,7 +241,11 @@ struct ws_win {
     Window            id;
     Window            transient;
     struct ws_win        *child_trans;    /* transient child window */
-    struct swm_geometry    g;
+    struct swm_geometry    g;        /* current geometry */
+    struct swm_geometry    g_float;    /* geometry when floating */
+    struct swm_geometry    rg_float;    /* region geom when floating */
+    int            g_floatvalid;    /* flag: geometry in g_float is valid */
+    int            floatmaxed;    /* flag: floater was maxed in max_stack */
     int            floating;
     int            manual;
     int            font_size_boundary[SWM_MAX_FONT_STEPS];
@@ -290,6 +294,9 @@ struct layout {
     { NULL,            NULL,            0,    NULL },
 };
 
+/* position of max_stack mode in the layouts array */
+#define SWM_MAX_STACK        2
+
 #define SWM_H_SLICE        (32)
 #define SWM_V_SLICE        (32)
 
@@ -346,6 +353,7 @@ union arg {
 #define SWM_ARG_ID_SWAPNEXT    (10)
 #define SWM_ARG_ID_SWAPPREV    (11)
 #define SWM_ARG_ID_SWAPMAIN    (12)
+#define SWM_ARG_ID_MOVELAST    (13)
 #define SWM_ARG_ID_MASTERSHRINK (20)
 #define SWM_ARG_ID_MASTERGROW    (21)
 #define SWM_ARG_ID_MASTERADD    (22)
@@ -1458,14 +1466,13 @@ switchws(struct swm_region *r, union arg
 
     other_r = new_ws->r;
     if (other_r == NULL) {
-        /* if the other workspace is hidden, switch windows */
-        if (old_ws->r != NULL)
-            old_ws->old_r = old_ws->r;
+        /* the other workspace is hidden, hide this one */
         old_ws->r = NULL;
 
         TAILQ_FOREACH(win, &old_ws->winlist, entry)
             unmap_window(win);
     } else {
+        /* the other ws is visible in another region, exchange them */
         other_r->ws = old_ws;
         old_ws->r = other_r;
     }
@@ -1615,6 +1622,10 @@ swapwin(struct swm_region *r, union arg 
         TAILQ_REMOVE(wl, source, entry);
         TAILQ_INSERT_HEAD(wl, source, entry);
         break;
+    case SWM_ARG_ID_MOVELAST:
+        TAILQ_REMOVE(wl, source, entry);
+        TAILQ_INSERT_TAIL(wl, source, entry);
+        break;
     default:
         DNPRINTF(SWM_D_MOVE, "invalid id: %d\n", args->id);
         return;
@@ -1804,6 +1815,8 @@ stack(void) {
                 g.h -= bar_height;
             }
             r->ws->cur_layout->l_stack(r->ws, &g);
+            /* save r so we can track region changes */
+            r->ws->old_r = r;
         }
     }
     if (font_adjusted)
@@ -1811,6 +1824,21 @@ stack(void) {
 }
 
 void
+store_float_geom(struct ws_win *win, struct swm_region *r)
+{
+    /* retain window geom and region geom */
+    win->g_float.x = win->g.x;
+    win->g_float.y = win->g.y;
+    win->g_float.w = win->g.w;
+    win->g_float.h = win->g.h;
+    win->rg_float.x = r->g.x;
+    win->rg_float.y = r->g.y;
+    win->rg_float.w = r->g.w;
+    win->rg_float.h = r->g.h;
+    win->g_floatvalid = 1;
+}
+
+void
 stack_floater(struct ws_win *win, struct swm_region *r)
 {
     unsigned int        mask;
@@ -1821,6 +1849,20 @@ stack_floater(struct ws_win *win, struct
 
     bzero(&wc, sizeof wc);
     mask = CWX | CWY | CWBorderWidth | CWWidth | CWHeight;
+
+    /* to allow windows to change their size (e.g. mplayer fs) only retrieve geom on ws switches or return from max mode */
+
+    if (win->floatmaxed || ( r != r->ws->old_r && win->g_floatvalid) ){
+        /* use stored g and rg to set relative position and size as in old region or before max stack mode */
+        win->g.x = win->g_float.x - win->rg_float.x + r->g.x;
+        win->g.y = win->g_float.y - win->rg_float.y + r->g.y;
+        win->g.w = win->g_float.w;
+        win->g.h = win->g_float.h;
+        win->g_floatvalid = 0;
+    }
+
+    win->floatmaxed = 0;
+
     if ((win->quirks & SWM_Q_FULLSCREEN) && (win->g.w >= WIDTH(r)) &&
         (win->g.h >= HEIGHT(r)))
         wc.border_width = 0;
@@ -1830,26 +1872,27 @@ stack_floater(struct ws_win *win, struct
         win->g.w = (double)WIDTH(r) * dialog_ratio;
         win->g.h = (double)HEIGHT(r) * dialog_ratio;
     }
+
+    if (!win->manual) {
+        /* floaters and transients are auto-centred unless moved or resized */
+                win->g.x = r->g.x + (WIDTH(r) - win->g.w) / 2;
+                win->g.y = r->g.y + (HEIGHT(r) - win->g.h) / 2;
+    }
+
+    /* win can be outside r if new r smaller than old r */
+    /* Ensure top left corner inside r (move probs otherwise) */
+    if ( win->g.x < r->g.x ) win->g.x = r->g.x;
+    if ( win->g.x > r->g.x + r->g.w - 1) win->g.x = (win->g.w > r->g.w) ? r->g.x : (r->g.x + r->g.w - win->g.w - 2);
+    if ( win->g.y < r->g.y ) win->g.y = r->g.y;
+    if ( win->g.y > r->g.y + r->g.h - 1) win->g.y = (win->g.h > r->g.h) ? r->g.y : (r->g.y + r->g.h - win->g.h - 2);
+
+    wc.x = win->g.x;
+    wc.y = win->g.y;
     wc.width = win->g.w;
     wc.height = win->g.h;
-    if (win->manual) {
-        wc.x = win->g.x;
-        wc.y = win->g.y;
-    } else {
-        wc.x = (WIDTH(r) - win->g.w) / 2;
-        wc.y = (HEIGHT(r) - win->g.h) / 2;
-    }
 
-    /* adjust for region */
-    if (wc.x < r->g.x)
-        wc.x += r->g.x;
-    if (wc.y < r->g.y)
-        wc.y += r->g.y;
-
-    win->g.x = wc.x;
-    win->g.y = wc.y;
-    win->g.w = wc.width;
-    win->g.h = wc.height;
+    /* Retain floater and transient geometry for correct positioning when ws changes region */
+    store_float_geom(win, r);
 
     DNPRINTF(SWM_D_MISC, "stack_floater: win %lu x %d y %d w %d h %d\n",
         win->id, wc.x, wc.y, wc.width, wc.height);
@@ -2160,7 +2203,7 @@ horizontal_config(struct workspace *ws, 
 void
 horizontal_stack(struct workspace *ws, struct swm_geometry *g)
 {
-    DNPRINTF(SWM_D_STACK, "vertical_stack: workspace: %d\n", ws->idx);
+    DNPRINTF(SWM_D_STACK, "horizontal_stack: workspace: %d\n", ws->idx);
 
     stack_master(ws, g, 1, 0);
 }
@@ -2191,6 +2234,12 @@ max_stack(struct workspace *ws, struct s
             continue;
         }
 
+        if (win->floating && win->floatmaxed == 0 ) {
+            /* retain geometry for retrieval on exit from max_stack mode */
+            store_float_geom(win, ws->r);
+            win->floatmaxed = 1;
+        }
+
         /* only reconfigure if necessary */
         if (win->g.x != gg.x || win->g.y != gg.y || win->g.w != gg.w ||
             win->g.h != gg.h) {
@@ -2286,8 +2335,27 @@ floating_toggle(struct swm_region *r, un
     if (win == NULL)
         return;
 
-    win->floating = !win->floating;
-    win->manual = 0;
+    /* reject floating toggles in max stack mode */
+    if (r->ws->cur_layout == &layouts[SWM_MAX_STACK])
+        return;
+
+    if (win->floating) {
+        if (!win->floatmaxed) {
+            /* retain position for refloat */
+            store_float_geom(win, r);
+        }
+        win->floating = 0;
+    } else {
+        if (win->g_floatvalid) {
+                        /* refloat at last floating relative position */
+                        win->g.x = win->g_float.x - win->rg_float.x + r->g.x;
+                        win->g.y = win->g_float.y - win->rg_float.y + r->g.y;
+                        win->g.w = win->g_float.w;
+                        win->g.h = win->g_float.h;
+                }
+        win->floating = 1;
+    }
+
     stack();
     a.id = SWM_ARG_ID_FOCUSCUR;
     focus(win->ws->r, &a);
@@ -2325,6 +2393,9 @@ resize(struct ws_win *win, union arg *ar
     XEvent            ev;
     Time            time = 0;
     struct swm_region    *r = win->ws->r;
+    int            relx, rely;
+    union arg        a;
+
 
     DNPRINTF(SWM_D_MOUSE, "resize: win %lu floating %d trans %lu\n",
         win->id, win->floating, win->transient);
@@ -2332,10 +2403,32 @@ resize(struct ws_win *win, union arg *ar
     if (!(win->transient != 0 || win->floating != 0))
         return;
 
+    /* reject resizes in max mode for floaters (transient ok) */
+    if (win->floatmaxed)
+        return;
+
+    win->manual = 1;
+    /* raise the window = move to last in window list */
+    a.id = SWM_ARG_ID_MOVELAST;
+    swapwin(r, &a);
+    stack();
+
     if (XGrabPointer(display, win->id, False, MOUSEMASK, GrabModeAsync,
         GrabModeAsync, None, None /* cursor */, CurrentTime) != GrabSuccess)
         return;
-    XWarpPointer(display, None, win->id, 0, 0, 0, 0, win->g.w, win->g.h);
+
+    /* place pointer at bottom left corner or nearest point inside r */
+    if ( win->g.x + win->g.w < r->g.x + r->g.w - 1)
+        relx = win->g.w;
+    else
+        relx = r->g.x + r->g.w - win->g.x - 2;
+
+    if ( win->g.y + win->g.h < r->g.y + r->g.h - 1)
+        rely = win->g.h;
+    else
+        rely = r->g.y + r->g.h - win->g.y - 2;
+
+    XWarpPointer(display, None, win->id, 0, 0, 0, 0, relx, rely);
     do {
         XMaskEvent(display, MOUSEMASK | ExposureMask |
             SubstructureRedirectMask, &ev);
@@ -2347,11 +2440,10 @@ resize(struct ws_win *win, union arg *ar
             break;
         case MotionNotify:
             /* do not allow resize outside of region */
-            if (ev.xmotion.y_root < r->g.y ||
-                ev.xmotion.y_root >= r->g.y + r->g.h - 1)
-                continue;
-            if (ev.xmotion.x_root < r->g.x ||
-                ev.xmotion.x_root >= r->g.x + r->g.w - 1)
+            if (    ev.xmotion.x_root < r->g.x ||
+                ev.xmotion.x_root > r->g.x + r->g.w - 1 ||
+                ev.xmotion.y_root < r->g.y ||
+                ev.xmotion.y_root > r->g.y + r->g.h - 1)
                 continue;
 
             if (ev.xmotion.x <= 1)
@@ -2374,6 +2466,8 @@ resize(struct ws_win *win, union arg *ar
         XSync(display, False);
         resize_window(win, args->id);
     }
+    store_float_geom(win,r);
+
     XWarpPointer(display, None, win->id, 0, 0, 0, 0, win->g.w - 1,
         win->g.h - 1);
     XUngrabPointer(display, CurrentTime);
@@ -2409,20 +2503,29 @@ move(struct ws_win *win, union arg *args
     Time            time = 0;
     int            restack = 0;
     struct swm_region    *r = win->ws->r;
+    union arg        a;
 
     DNPRINTF(SWM_D_MOUSE, "move: win %lu floating %d trans %lu\n",
         win->id, win->floating, win->transient);
 
-    if (win->floating == 0) {
+    /* in max_stack mode should only move transients */
+    if (win->ws->cur_layout == &layouts[SWM_MAX_STACK] && !win->transient)
+        return;
+
+    win->manual = 1;
+    if (win->floating == 0 && !win->transient) {
         win->floating = 1;
-        win->manual = 1;
-        restack = 1;
     }
 
+    /* raise the window = move to last in window list */
+    a.id = SWM_ARG_ID_MOVELAST;
+    swapwin(r, &a);
+    stack();
+
     if (XGrabPointer(display, win->id, False, MOUSEMASK, GrabModeAsync,
         GrabModeAsync, None, None /* cursor */, CurrentTime) != GrabSuccess)
         return;
-    XWarpPointer(display, None, win->id, 0, 0, 0, 0, 0, 0);
+    XWarpPointer(display, None, win->id, 0, 0, 0, 0, -1, -1);
     do {
         XMaskEvent(display, MOUSEMASK | ExposureMask |
             SubstructureRedirectMask, &ev);
@@ -2433,12 +2536,11 @@ move(struct ws_win *win, union arg *args
             handler[ev.type](&ev);
             break;
         case MotionNotify:
-            /* don't allow to move window out of region */
-            if (ev.xmotion.y_root < r->g.y ||
-                ev.xmotion.y_root + win->g.h >= r->g.y + r->g.h - 1)
-                continue;
-            if (ev.xmotion.x_root < r->g.x ||
-                ev.xmotion.x_root + win->g.w >= r->g.x + r->g.w - 1)
+            /* don't allow to move window origin out of region */
+            if (    ev.xmotion.x_root < r->g.x ||
+                ev.xmotion.x_root > r->g.x + r->g.w - 1 ||
+                ev.xmotion.y_root < r->g.y ||
+                ev.xmotion.y_root > r->g.y + r->g.h - 1)
                 continue;
 
             win->g.x = ev.xmotion.x_root;
@@ -2457,10 +2559,9 @@ move(struct ws_win *win, union arg *args
         XSync(display, False);
         move_window(win);
     }
+    store_float_geom(win,r);
     XWarpPointer(display, None, win->id, 0, 0, 0, 0, 0, 0);
     XUngrabPointer(display, CurrentTime);
-    if (restack)
-        stack();
 
     /* drain events */
     while (XCheckMaskEvent(display, EnterWindowMask, &ev));
@@ -3694,6 +3795,8 @@ manage_window(Window id)
     win->g.h = win->wa.height;
     win->g.x = win->wa.x;
     win->g.y = win->wa.y;
+    win->g_floatvalid = 0;
+    win->floatmaxed = 0;
 
     /* Set window properties so we can remember this after reincarnation */
     if (ws_idx_atom && prop == NULL &&

And here is the _cumulative_ patch of patches 1 to 8 (you need just this one):

--- scrotwm.c    2010-01-21 10:12:11.598822491 +0000
+++ scrotwm.patched1-8.c    2010-01-21 09:34:34.208084359 +0000
@@ -98,7 +98,7 @@ static const char    *cvstag = "$scrotwm: s
 #endif
 #endif
 
-/* #define SWM_DEBUG */
+#define SWM_DEBUG
 #ifdef SWM_DEBUG
 #define DPRINTF(x...)        do { if (swm_debug) fprintf(stderr, x); } while (0)
 #define DNPRINTF(n,x...)    do { if (swm_debug & n) fprintf(stderr, x); } while (0)
@@ -183,7 +183,7 @@ unsigned int        mod_key = MODKEY;
 /* dialog windows */
 double            dialog_ratio = .6;
 /* status bar */
-#define SWM_BAR_MAX    (256)
+#define SWM_BAR_MAX    (1024)
 char            *bar_argv[] = { NULL, NULL };
 int            bar_pipe[2];
 char            bar_ext[SWM_BAR_MAX];
@@ -241,7 +241,11 @@ struct ws_win {
     Window            id;
     Window            transient;
     struct ws_win        *child_trans;    /* transient child window */
-    struct swm_geometry    g;
+    struct swm_geometry    g;        /* current geometry */
+    struct swm_geometry    g_float;    /* geometry when floating */
+    struct swm_geometry    rg_float;    /* region geom when floating */
+    int            g_floatvalid;    /* flag: geometry in g_float is valid */
+    int            floatmaxed;    /* flag: floater was maxed in max_stack */
     int            floating;
     int            manual;
     int            font_size_boundary[SWM_MAX_FONT_STEPS];
@@ -290,6 +294,9 @@ struct layout {
     { NULL,            NULL,            0,    NULL },
 };
 
+/* position of max_stack mode in the layouts array */
+#define SWM_MAX_STACK        2
+
 #define SWM_H_SLICE        (32)
 #define SWM_V_SLICE        (32)
 
@@ -346,6 +353,7 @@ union arg {
 #define SWM_ARG_ID_SWAPNEXT    (10)
 #define SWM_ARG_ID_SWAPPREV    (11)
 #define SWM_ARG_ID_SWAPMAIN    (12)
+#define SWM_ARG_ID_MOVELAST    (13)
 #define SWM_ARG_ID_MASTERSHRINK (20)
 #define SWM_ARG_ID_MASTERGROW    (21)
 #define SWM_ARG_ID_MASTERADD    (22)
@@ -698,13 +706,62 @@ socket_setnonblock(int fd)
         err(1, "fcntl F_SETFL");
 }
 
+#define SWM_MAX_COLOR_LEN 40
 void
 bar_print(struct swm_region *r, char *s)
 {
+/* print s in the bar, parsing and applying any inline color tags */
+/* formats include: ^fg(rgb:12/fa/43), ^fg(red), ^fg(#12fa43) */
+        int is = 0, ig = 0, k, ic = 0, iu = 0;
+    int xpos = 4;             /* starting x position */
+        const char *g = "^fg(";   /* the foregroud color tag */
+        char u[SWM_BAR_MAX];     /* section of text between tags */
+        char cname[SWM_MAX_COLOR_LEN];
+    unsigned long color;
+
     XClearWindow(display, r->bar_window);
     XSetForeground(display, bar_gc, r->s->c[SWM_S_COLOR_BAR_FONT].color);
-    XDrawString(display, r->bar_window, bar_gc, 4, bar_fs->ascent, s,
-        strlen(s));
+
+        while (s[is] != '\0' && iu < (SWM_BAR_MAX-1)) {
+                if ( s[is] != g[ig] ) {
+                        if (ig != 0) {
+                /* partial tag not full one, catch up */
+                                for (k = 0; k < ig; k++) {
+                                        u[iu++] = s[is-ig+k];
+                                }
+                                ig = 0; //reset tag search
+                        }
+                        u[iu++]=s[is++];
+                } else {
+                        if (ig == strlen(g)-1) {
+                                /* found full tag: print previous section */
+                                u[iu] = '\0';
+                XDrawString(display, r->bar_window, bar_gc, xpos, bar_fs->ascent, u, strlen(u));
+                xpos += XTextWidth(bar_fs, u, strlen(u));
+                                is++;
+                                /* read and set new colour */
+                                for (ic = 0; ic < (SWM_MAX_COLOR_LEN-1) && s[is] != ')'; is++, ic++) {
+                                        cname[ic] = s[is];
+                                }
+                                cname[ic] = '\0';
+                if (s[is] == ')') {
+                    color = name_to_color(cname);
+                    XSetForeground(display, bar_gc, color);
+                }
+                                /* reset tag search */
+                                is += 1;
+                                iu = 0;
+                                ig = 0;
+                        } else {
+                                /* partial tag, look for next tag char */
+                                is++;
+                                ig++;
+                        }
+                }
+        }
+        /* final part of the string */
+        u[iu] = '\0';
+    XDrawString(display, r->bar_window, bar_gc, xpos, bar_fs->ascent, u, strlen(u));
 }
 
 void
@@ -1225,7 +1282,7 @@ spawn(struct swm_region *r, union arg *a
         if (fork() == 0) {
             if (display)
                 close(ConnectionNumber(display));
-            setenv("LD_PRELOAD", SWM_LIB, 1);
+            //setenv("LD_PRELOAD", SWM_LIB, 1);
             if (asprintf(&ret, "%d", r->ws->idx)) {
                 setenv("_SWM_WS", ret, 1);
                 free(ret);
@@ -1458,14 +1515,13 @@ switchws(struct swm_region *r, union arg
 
     other_r = new_ws->r;
     if (other_r == NULL) {
-        /* if the other workspace is hidden, switch windows */
-        if (old_ws->r != NULL)
-            old_ws->old_r = old_ws->r;
+        /* the other workspace is hidden, hide this one */
         old_ws->r = NULL;
 
         TAILQ_FOREACH(win, &old_ws->winlist, entry)
             unmap_window(win);
     } else {
+        /* the other ws is visible in another region, exchange them */
         other_r->ws = old_ws;
         old_ws->r = other_r;
     }
@@ -1523,10 +1579,6 @@ cyclescr(struct swm_region *r, union arg
     union arg        a;
     int            i, x, y;
 
-    /* do nothing if we don't have more than one screen */
-    if (!(ScreenCount(display) > 1 || outputs > 1))
-        return;
-
     i = r->s->idx;
     switch (args->id) {
     case SWM_ARG_ID_CYCLESC_UP:
@@ -1547,7 +1599,7 @@ cyclescr(struct swm_region *r, union arg
 
     /* move mouse to region */
     x = rr->g.x + 1;
-    y = rr->g.y + 1 + bar_enabled ? bar_height : 0;
+    y = rr->g.y + 1 + (bar_enabled ? bar_height : 0);
     XWarpPointer(display, None, rr->s[i].root, 0, 0, 0, 0, x, y);
 
     a.id = SWM_ARG_ID_FOCUSCUR;
@@ -1615,6 +1667,10 @@ swapwin(struct swm_region *r, union arg 
         TAILQ_REMOVE(wl, source, entry);
         TAILQ_INSERT_HEAD(wl, source, entry);
         break;
+    case SWM_ARG_ID_MOVELAST:
+        TAILQ_REMOVE(wl, source, entry);
+        TAILQ_INSERT_TAIL(wl, source, entry);
+        break;
     default:
         DNPRINTF(SWM_D_MOVE, "invalid id: %d\n", args->id);
         return;
@@ -1804,6 +1860,8 @@ stack(void) {
                 g.h -= bar_height;
             }
             r->ws->cur_layout->l_stack(r->ws, &g);
+            /* save r so we can track region changes */
+            r->ws->old_r = r;
         }
     }
     if (font_adjusted)
@@ -1811,6 +1869,21 @@ stack(void) {
 }
 
 void
+store_float_geom(struct ws_win *win, struct swm_region *r)
+{
+    /* retain window geom and region geom */
+    win->g_float.x = win->g.x;
+    win->g_float.y = win->g.y;
+    win->g_float.w = win->g.w;
+    win->g_float.h = win->g.h;
+    win->rg_float.x = r->g.x;
+    win->rg_float.y = r->g.y;
+    win->rg_float.w = r->g.w;
+    win->rg_float.h = r->g.h;
+    win->g_floatvalid = 1;
+}
+
+void
 stack_floater(struct ws_win *win, struct swm_region *r)
 {
     unsigned int        mask;
@@ -1821,6 +1894,20 @@ stack_floater(struct ws_win *win, struct
 
     bzero(&wc, sizeof wc);
     mask = CWX | CWY | CWBorderWidth | CWWidth | CWHeight;
+
+    /* to allow windows to change their size (e.g. mplayer fs) only retrieve geom on ws switches or return from max mode */
+
+    if (win->floatmaxed || ( r != r->ws->old_r && win->g_floatvalid) ){
+        /* use stored g and rg to set relative position and size as in old region or before max stack mode */
+        win->g.x = win->g_float.x - win->rg_float.x + r->g.x;
+        win->g.y = win->g_float.y - win->rg_float.y + r->g.y;
+        win->g.w = win->g_float.w;
+        win->g.h = win->g_float.h;
+        win->g_floatvalid = 0;
+    }
+
+    win->floatmaxed = 0;
+
     if ((win->quirks & SWM_Q_FULLSCREEN) && (win->g.w >= WIDTH(r)) &&
         (win->g.h >= HEIGHT(r)))
         wc.border_width = 0;
@@ -1830,26 +1917,27 @@ stack_floater(struct ws_win *win, struct
         win->g.w = (double)WIDTH(r) * dialog_ratio;
         win->g.h = (double)HEIGHT(r) * dialog_ratio;
     }
+
+    if (!win->manual) {
+        /* floaters and transients are auto-centred unless moved or resized */
+                win->g.x = r->g.x + (WIDTH(r) - win->g.w) / 2;
+                win->g.y = r->g.y + (HEIGHT(r) - win->g.h) / 2;
+    }
+
+    /* win can be outside r if new r smaller than old r */
+    /* Ensure top left corner inside r (move probs otherwise) */
+    if ( win->g.x < r->g.x ) win->g.x = r->g.x;
+    if ( win->g.x > r->g.x + r->g.w - 1) win->g.x = (win->g.w > r->g.w) ? r->g.x : (r->g.x + r->g.w - win->g.w - 2);
+    if ( win->g.y < r->g.y ) win->g.y = r->g.y;
+    if ( win->g.y > r->g.y + r->g.h - 1) win->g.y = (win->g.h > r->g.h) ? r->g.y : (r->g.y + r->g.h - win->g.h - 2);
+
+    wc.x = win->g.x;
+    wc.y = win->g.y;
     wc.width = win->g.w;
     wc.height = win->g.h;
-    if (win->manual) {
-        wc.x = win->g.x;
-        wc.y = win->g.y;
-    } else {
-        wc.x = (WIDTH(r) - win->g.w) / 2;
-        wc.y = (HEIGHT(r) - win->g.h) / 2;
-    }
 
-    /* adjust for region */
-    if (wc.x < r->g.x)
-        wc.x += r->g.x;
-    if (wc.y < r->g.y)
-        wc.y += r->g.y;
-
-    win->g.x = wc.x;
-    win->g.y = wc.y;
-    win->g.w = wc.width;
-    win->g.h = wc.height;
+    /* Retain floater and transient geometry for correct positioning when ws changes region */
+    store_float_geom(win, r);
 
     DNPRINTF(SWM_D_MISC, "stack_floater: win %lu x %d y %d w %d h %d\n",
         win->id, wc.x, wc.y, wc.width, wc.height);
@@ -2023,7 +2111,12 @@ stack_master(struct workspace *ws, struc
             win_g.y += last_h + 2;
 
         bzero(&wc, sizeof wc);
-        wc.border_width = 1;
+        if (bar_enabled == 0 && winno == 1){
+            wc.border_width = 0;
+            win_g.w += 2;
+            win_g.h += 2;
+        } else
+            wc.border_width = 1;
         reconfigure = 0;
         if (rot) {
             if (win->g.x != win_g.y || win->g.y != win_g.x ||
@@ -2160,7 +2253,7 @@ horizontal_config(struct workspace *ws, 
 void
 horizontal_stack(struct workspace *ws, struct swm_geometry *g)
 {
-    DNPRINTF(SWM_D_STACK, "vertical_stack: workspace: %d\n", ws->idx);
+    DNPRINTF(SWM_D_STACK, "horizontal_stack: workspace: %d\n", ws->idx);
 
     stack_master(ws, g, 1, 0);
 }
@@ -2191,15 +2284,27 @@ max_stack(struct workspace *ws, struct s
             continue;
         }
 
+        if (win->floating && win->floatmaxed == 0 ) {
+            /* retain geometry for retrieval on exit from max_stack mode */
+            store_float_geom(win, ws->r);
+            win->floatmaxed = 1;
+        }
+
         /* only reconfigure if necessary */
         if (win->g.x != gg.x || win->g.y != gg.y || win->g.w != gg.w ||
             win->g.h != gg.h) {
             bzero(&wc, sizeof wc);
-            wc.border_width = 1;
             win->g.x = wc.x = gg.x;
             win->g.y = wc.y = gg.y;
-            win->g.w = wc.width = gg.w;
-            win->g.h = wc.height = gg.h;
+            if (bar_enabled){
+                wc.border_width = 1;
+                win->g.w = wc.width = gg.w;
+                win->g.h = wc.height = gg.h;
+            } else {
+                wc.border_width = 0;
+                win->g.w = wc.width = gg.w + 2;
+                win->g.h = wc.height = gg.h + 2;
+            }
             mask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
             XConfigureWindow(display, win->id, mask, &wc);
             configreq_win(win);
@@ -2286,8 +2391,27 @@ floating_toggle(struct swm_region *r, un
     if (win == NULL)
         return;
 
-    win->floating = !win->floating;
-    win->manual = 0;
+    /* reject floating toggles in max stack mode */
+    if (r->ws->cur_layout == &layouts[SWM_MAX_STACK])
+        return;
+
+    if (win->floating) {
+        if (!win->floatmaxed) {
+            /* retain position for refloat */
+            store_float_geom(win, r);
+        }
+        win->floating = 0;
+    } else {
+        if (win->g_floatvalid) {
+                        /* refloat at last floating relative position */
+                        win->g.x = win->g_float.x - win->rg_float.x + r->g.x;
+                        win->g.y = win->g_float.y - win->rg_float.y + r->g.y;
+                        win->g.w = win->g_float.w;
+                        win->g.h = win->g_float.h;
+                }
+        win->floating = 1;
+    }
+
     stack();
     a.id = SWM_ARG_ID_FOCUSCUR;
     focus(win->ws->r, &a);
@@ -2325,6 +2449,9 @@ resize(struct ws_win *win, union arg *ar
     XEvent            ev;
     Time            time = 0;
     struct swm_region    *r = win->ws->r;
+    int            relx, rely;
+    union arg        a;
+
 
     DNPRINTF(SWM_D_MOUSE, "resize: win %lu floating %d trans %lu\n",
         win->id, win->floating, win->transient);
@@ -2332,10 +2459,32 @@ resize(struct ws_win *win, union arg *ar
     if (!(win->transient != 0 || win->floating != 0))
         return;
 
+    /* reject resizes in max mode for floaters (transient ok) */
+    if (win->floatmaxed)
+        return;
+
+    win->manual = 1;
+    /* raise the window = move to last in window list */
+    a.id = SWM_ARG_ID_MOVELAST;
+    swapwin(r, &a);
+    stack();
+
     if (XGrabPointer(display, win->id, False, MOUSEMASK, GrabModeAsync,
         GrabModeAsync, None, None /* cursor */, CurrentTime) != GrabSuccess)
         return;
-    XWarpPointer(display, None, win->id, 0, 0, 0, 0, win->g.w, win->g.h);
+
+    /* place pointer at bottom left corner or nearest point inside r */
+    if ( win->g.x + win->g.w < r->g.x + r->g.w - 1)
+        relx = win->g.w;
+    else
+        relx = r->g.x + r->g.w - win->g.x - 2;
+
+    if ( win->g.y + win->g.h < r->g.y + r->g.h - 1)
+        rely = win->g.h;
+    else
+        rely = r->g.y + r->g.h - win->g.y - 2;
+
+    XWarpPointer(display, None, win->id, 0, 0, 0, 0, relx, rely);
     do {
         XMaskEvent(display, MOUSEMASK | ExposureMask |
             SubstructureRedirectMask, &ev);
@@ -2347,11 +2496,10 @@ resize(struct ws_win *win, union arg *ar
             break;
         case MotionNotify:
             /* do not allow resize outside of region */
-            if (ev.xmotion.y_root < r->g.y ||
-                ev.xmotion.y_root >= r->g.y + r->g.h - 1)
-                continue;
-            if (ev.xmotion.x_root < r->g.x ||
-                ev.xmotion.x_root >= r->g.x + r->g.w - 1)
+            if (    ev.xmotion.x_root < r->g.x ||
+                ev.xmotion.x_root > r->g.x + r->g.w - 1 ||
+                ev.xmotion.y_root < r->g.y ||
+                ev.xmotion.y_root > r->g.y + r->g.h - 1)
                 continue;
 
             if (ev.xmotion.x <= 1)
@@ -2374,6 +2522,8 @@ resize(struct ws_win *win, union arg *ar
         XSync(display, False);
         resize_window(win, args->id);
     }
+    store_float_geom(win,r);
+
     XWarpPointer(display, None, win->id, 0, 0, 0, 0, win->g.w - 1,
         win->g.h - 1);
     XUngrabPointer(display, CurrentTime);
@@ -2409,20 +2559,29 @@ move(struct ws_win *win, union arg *args
     Time            time = 0;
     int            restack = 0;
     struct swm_region    *r = win->ws->r;
+    union arg        a;
 
     DNPRINTF(SWM_D_MOUSE, "move: win %lu floating %d trans %lu\n",
         win->id, win->floating, win->transient);
 
-    if (win->floating == 0) {
+    /* in max_stack mode should only move transients */
+    if (win->ws->cur_layout == &layouts[SWM_MAX_STACK] && !win->transient)
+        return;
+
+    win->manual = 1;
+    if (win->floating == 0 && !win->transient) {
         win->floating = 1;
-        win->manual = 1;
-        restack = 1;
     }
 
+    /* raise the window = move to last in window list */
+    a.id = SWM_ARG_ID_MOVELAST;
+    swapwin(r, &a);
+    stack();
+
     if (XGrabPointer(display, win->id, False, MOUSEMASK, GrabModeAsync,
         GrabModeAsync, None, None /* cursor */, CurrentTime) != GrabSuccess)
         return;
-    XWarpPointer(display, None, win->id, 0, 0, 0, 0, 0, 0);
+    XWarpPointer(display, None, win->id, 0, 0, 0, 0, -1, -1);
     do {
         XMaskEvent(display, MOUSEMASK | ExposureMask |
             SubstructureRedirectMask, &ev);
@@ -2433,12 +2592,11 @@ move(struct ws_win *win, union arg *args
             handler[ev.type](&ev);
             break;
         case MotionNotify:
-            /* don't allow to move window out of region */
-            if (ev.xmotion.y_root < r->g.y ||
-                ev.xmotion.y_root + win->g.h >= r->g.y + r->g.h - 1)
-                continue;
-            if (ev.xmotion.x_root < r->g.x ||
-                ev.xmotion.x_root + win->g.w >= r->g.x + r->g.w - 1)
+            /* don't allow to move window origin out of region */
+            if (    ev.xmotion.x_root < r->g.x ||
+                ev.xmotion.x_root > r->g.x + r->g.w - 1 ||
+                ev.xmotion.y_root < r->g.y ||
+                ev.xmotion.y_root > r->g.y + r->g.h - 1)
                 continue;
 
             win->g.x = ev.xmotion.x_root;
@@ -2457,10 +2615,9 @@ move(struct ws_win *win, union arg *args
         XSync(display, False);
         move_window(win);
     }
+    store_float_geom(win,r);
     XWarpPointer(display, None, win->id, 0, 0, 0, 0, 0, 0);
     XUngrabPointer(display, CurrentTime);
-    if (restack)
-        stack();
 
     /* drain events */
     while (XCheckMaskEvent(display, EnterWindowMask, &ev));
@@ -3694,6 +3851,8 @@ manage_window(Window id)
     win->g.h = win->wa.height;
     win->g.x = win->wa.x;
     win->g.y = win->wa.y;
+    win->g_floatvalid = 0;
+    win->floatmaxed = 0;
 
     /* Set window properties so we can remember this after reincarnation */
     if (ws_idx_atom && prop == NULL &&
@@ -4108,10 +4267,6 @@ focusme:
 void
 focusevent(XEvent *e)
 {
-    DNPRINTF(SWM_D_EVENT, "focusevent: %s window: %lu mode %d detail %d\n",
-        ev->type == FocusIn ? "entering" : "leaving",
-        ev->window, ev->mode, ev->detail);
-#if 0
     struct ws_win        *win;
     u_int32_t        mode_detail;
     XFocusChangeEvent    *ev = &e->xfocus;
@@ -4119,7 +4274,7 @@ focusevent(XEvent *e)
     DNPRINTF(SWM_D_EVENT, "focusevent: %s window: %lu mode %d detail %d\n",
         ev->type == FocusIn ? "entering" : "leaving",
         ev->window, ev->mode, ev->detail);
-
+#if 0
     if (last_focus_event == ev->type) {
         DNPRINTF(SWM_D_FOCUS, "ignoring focusevent: bad ordering\n");
         return;
@@ -4322,6 +4477,8 @@ new_region(struct swm_screen *s, int x, 
             (X(r) + WIDTH(r)) > x &&
             Y(r) < (y + h) &&
             (Y(r) + HEIGHT(r)) > y) {
+            /* ensure ws doesn't point to dead region */
+            r->ws->r = NULL;
             XDestroyWindow(display, r->bar_window);
             TAILQ_REMOVE(&s->rl, r, entry);
             TAILQ_INSERT_TAIL(&s->orl, r, entry);
@@ -4712,11 +4869,10 @@ main(int argc, char *argv[])
                 winfocus = NULL;
                 continue;
             }
-            /* move pointer to first screen if multi screen */
-            if (ScreenCount(display) > 1 || outputs > 1)
-                XWarpPointer(display, None, rr->s[0].root,
-                    0, 0, 0, 0, rr->g.x,
-                    rr->g.y + bar_enabled ? bar_height : 0);
+            /* move pointer to first screen */
+            XWarpPointer(display, None, rr->s[0].root,
+                0, 0, 0, 0, rr->g.x,
+                rr->g.y + (bar_enabled ? bar_height : 0));
 
             a.id = SWM_ARG_ID_FOCUSCUR;
             focus(rr, &a);

Offline

#171 2010-01-25 04:54:46

zowki
Member
From: Trapped in The Matrix
Registered: 2008-11-27
Posts: 582
Website

Re: Scrotwm / Spectrwm

Bug report: Notifications through the xfce notification daemon (and possibly through other notification daemons) which are supposed to be pop up bubbles in the top right of the screen become tiled along with other windows.


How's my programming? Call 1-800-DEV-NULL

Offline

#172 2010-01-26 02:00:27

Aedit
Member
Registered: 2009-10-29
Posts: 138

Re: Scrotwm / Spectrwm

Have you tried adding a quirk for the notification windows in the configuration file, with options FLOAT + ANYWHERE ?

Offline

#173 2010-01-26 08:43:19

zowki
Member
From: Trapped in The Matrix
Registered: 2008-11-27
Posts: 582
Website

Re: Scrotwm / Spectrwm

I don't know what the notification window titles are so how can I add a quirk?


How's my programming? Call 1-800-DEV-NULL

Offline

#174 2010-01-26 10:48:46

Aedit
Member
Registered: 2009-10-29
Posts: 138

Re: Scrotwm / Spectrwm

Put this in the config file to show the name and class in the status bar

title_name_enabled      = 1
title_class_enabled     = 1

Offline

#175 2010-01-27 05:38:36

axion419
Member
Registered: 2007-04-12
Posts: 185

Re: Scrotwm / Spectrwm

just started using scrotwm to replace dwm and everything is going great.  I just wanted to know if there is a way to pipe my conky-cli into the status bar.  I tried doing it the way I did in dwm but it did not work.  Also, how does one increase the border of the active window?  I looked around the config and could not find the answer.  Thanks.

Offline

Board footer

Powered by FluxBB