saloniamatteo/dwm

Floating window gets pushed left when moving to the right side of the screen

eeeXun opened this issue · 13 comments

When the window in floating mode, and drag it to a specific area, it would overflow or something.

ezgif com-gif-maker

I have spent a few hours trying to fix the bug, but so far I haven't made any progress.

I will continue another time; Any help is appreciated.

That's fine.By the way,your dwm is very awesome.

Thanks 😁

The problem is with the custom systray patch ([dwm-systray.diff], in the dwm.c 'drawbar' function exactly . Here is the fixed function just replace it:

void drawbar(Monitor *m) {
  int x, w, tw = 0, stw = 0;
  int boxs = drw->fonts->h / 9;
  int boxw = drw->fonts->h / 6 + 2;
  unsigned int i, occ = 0, urg = 0;
  Client *c;

  if (showsystray && m == systraytomon(m))
    stw = getsystraywidth();

  /* draw status first so it can be overdrawn by tags later */
  if (m == selmon) { /* status is only drawn on selected monitor */
    drw_setscheme(drw, scheme[SchemeNorm]);
    tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */
    drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, stext, 0);
  }

  resizebarwin(m);
  for (c = m->clients; c; c = c->next) {
    occ |= c->tags == 255 ? 0 : c->tags;
    if (c->isurgent)
      urg |= c->tags;
  }
  x = 0;
  for (i = 0; i < LENGTH(tags); i++) {
    /* do not draw vacant tags */
    if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
      continue;

    w = TEXTW(tags[i]);
    drw_setscheme(
        drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
    drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);

    if (occ & 1 << i)
      drw_rect(drw, x + boxs, boxs, boxw, boxw,
               m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
               urg & 1 << i);

    x += w;
  }
  w = blw = TEXTW(m->ltsymbol);
  drw_setscheme(drw, scheme[SchemeNorm]);
  x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);

  if ((w = m->ww - tw - stw - x) > bh) {
    if (m->sel) {
      drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
      drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
      if (m->sel->isfloating)
        drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
    } else {
      drw_setscheme(drw, scheme[SchemeNorm]);
      drw_rect(drw, x, 0, w, bh, 1, 1);
    }
  }

  drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh);
}

The exact lines that were changed in this function are:

int x, w, stw = 0; --> to: int x, w, tw = 0, stw = 0;

sw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */ --> to    tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */

drw_text(drw, m->ww - sw - stw, 0, sw, bh, lrpad / 2 - 2, stext, 0); --> to: drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, stext, 0);

if ((w = m->ww - sw - stw - x) > bh) { --> to: if ((w = m->ww - tw - stw - x) > bh) {

Thank you very much for commenting! I will try out this patch later on in the day, and will update the code if everything goes well.

Hi @nicksaprigkin, I am afraid I have tried your patch, only to find out not only does it not work, but the systray (as well as the whole bar for dwmblocks) gets removed as well (as in, there is no space for it).

Anyway, one of these days I ought to start this from scratch: get dwm sources, get patches, and fix everything...

@saloniamatteo was this commented or you edited it? c/* draw status first so it can be overdrawn by tags later / if (m == selmon) { / status is only drawn on selected monitor / drw_setscheme(drw, scheme[SchemeNorm]); tw = TEXTW(stext) - lrpad / 2 + 2; / 2px right padding */
if it was then my bad i also forgot to list it in the "lines that were changed:" c sw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */ --> to tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */
if you commented then it i guess it works for my monitor or something...!

I updated the original comment btw

Also I found this! so maybe the problem is with the version of dwm. I have version 6.2 and in that version its tw instead of sw. I found this in reddit:
image
link: https://git.suckless.org/dwm/commit/ed3ab6b4fceded0e9f2d22372df49a2bbd58de66.html
so I guess my solution works for dwm 6.2 and maybe @eeeXun has it too.

@eeeXun @nicksaprigkin, I'd like to let you know that I now updated this build to 6.5, and re-applied all patches from scratch, also solving this issue.

@nicksaprigkin

Hi Nick,

I apologize for reaching out. My question is not related to this build, but I have a very similar issue with floating windows on dwm 6.2.

Could you please help me resolve the issue in my case? I would greatly appreciate any recommendations.

void
drawbar(Monitor *m)
{
	int x, w, tw = 0;
	int boxs = drw->fonts->h / 9;
	int boxw = drw->fonts->h / 6 + 2;
	unsigned int i, occ = 0, urg = 0;
	Client *c;

	/* draw status first so it can be overdrawn by tags later */
    if (m == selmon || 1) { /* status is only drawn on selected monitor */
        sw = m->ww - drawstatusbar(m, bh, stext) - 2 * sp - 10;
        tw = sw; // status2d fix
    }

	for (c = m->clients; c; c = c->next) {
		occ |= c->tags == 255 ? 0 : c->tags;
		if (c->isurgent)
			urg |= c->tags;
	}
	x = 0;
	for (i = 0; i < LENGTH(tags); i++) {
		/* do not draw vacant tags */
		if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
		continue;

		w = TEXTW(tags[i]);
		drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
		drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
		x += w;
	}
	w = blw = TEXTW(m->ltsymbol);
	drw_setscheme(drw, scheme[SchemeNorm]);
	x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);

	if ((w = m->ww - tw - x) > bh) {
		if (m->sel) {
            /* fix overflow when window name is bigger than window width */
			int mid = (m->ww - (int)TEXTW(m->sel->name)) / 2 - x;
			/* make sure name will not overlap on tags even when it is very long */
			mid = mid >= lrpad / 2 ? mid : lrpad / 2;
			drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
			drw_text(drw, x, 0, w -2 * sp - 10, bh, mid, m->sel->name, 0);
			if (m->sel->isfloating)
				drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
		} else {
			drw_setscheme(drw, scheme[SchemeNorm]);
			drw_rect(drw, x, 0, w -2 * sp - 10, bh, 1, 1);
		}
	}

    fprintf(stderr, "Mapping bar window: x=0, y=0, width=%d, height=%d\n", m->ww, bh);

	drw_map(drw, m->barwin, 0, 0, m->ww, bh);
}

It solved here -
https://www.reddit.com/r/suckless/comments/1i44pf4/dwm_62_the_floating_window_shifts_to_the_left/

@nicksaprigkin

Hi Nick,

I apologize for reaching out. My question is not related to this build, but I have a very similar issue with floating windows on dwm 6.2.

Could you please help me resolve the issue in my case? I would greatly appreciate any recommendations.

void
drawbar(Monitor *m)
{
int x, w, tw = 0;
int boxs = drw->fonts->h / 9;
int boxw = drw->fonts->h / 6 + 2;
unsigned int i, occ = 0, urg = 0;
Client *c;

/* draw status first so it can be overdrawn by tags later /
if (m == selmon || 1) { /
status is only drawn on selected monitor */
sw = m->ww - drawstatusbar(m, bh, stext) - 2 * sp - 10;
tw = sw; // status2d fix
}

for (c = m->clients; c; c = c->next) {
occ |= c->tags == 255 ? 0 : c->tags;
if (c->isurgent)
urg |= c->tags;
}
x = 0;
for (i = 0; i < LENGTH(tags); i++) {
/* do not draw vacant tags */
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
continue;

  w = TEXTW(tags[i]);
  drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
  drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
  x += w;

}
w = blw = TEXTW(m->ltsymbol);
drw_setscheme(drw, scheme[SchemeNorm]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);

if ((w = m->ww - tw - x) > bh) {
if (m->sel) {
/* fix overflow when window name is bigger than window width /
int mid = (m->ww - (int)TEXTW(m->sel->name)) / 2 - x;
/
make sure name will not overlap on tags even when it is very long */
mid = mid >= lrpad / 2 ? mid : lrpad / 2;
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
drw_text(drw, x, 0, w -2 * sp - 10, bh, mid, m->sel->name, 0);
if (m->sel->isfloating)
drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
} else {
drw_setscheme(drw, scheme[SchemeNorm]);
drw_rect(drw, x, 0, w -2 * sp - 10, bh, 1, 1);
}
}

fprintf(stderr, "Mapping bar window: x=0, y=0, width=%d, height=%d\n", m->ww, bh);

drw_map(drw, m->barwin, 0, 0, m->ww, bh);
}