You are not logged in.
@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
fabulous! thank you all.
Offline
@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
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!
If you don't mind, I second this (very important) question.
EDIT>
Btw, #scrotwm on Freenode awaits you
Last edited by virus_found (2009-12-20 17:11:25)
Offline
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!
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
Thank you very much for this! This should be definitely pushed to cvs.
Offline
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
The first time I read it....I read scrotum HAHAHHAHA
HAHA
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
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
There have recently been some commits to the cvs, and all your patches fail to apply, unfortunately.
Offline
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
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
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
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
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
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
Please mail them anyway :-)
Make sure they are run with diff -uNp
Offline
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
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
@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
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
Have you tried adding a quirk for the notification windows in the configuration file, with options FLOAT + ANYWHERE ?
Offline
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
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
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