X-DWM——帮助我修复C源代码中的一个bug
我正在使用(6.2)窗口管理器,我发现了一个我很想解决的bug 窗口管理器在放置窗口的位置使用“主区域”和“堆栈区域”: 可以使用ALT+i将“堆栈区域”顶部的窗口移动到“主区域”底部。也可以使用ALT+d将窗口从“主区域”的底部移回“堆栈区域”的顶部 现在,在这种情况下,如果我使用ALT+I,布局会改变,在组合键之后,“主区域”中有两个窗口: 我再重复一遍,现在“主区域”中有三个窗口: 我再重复一遍,现在“主区域”中有三个窗口,宽度为100%: 如果此时我决定将窗口从“主区域”返回到“堆栈区域”,我将开始按ALT+d,windows将立即返回到“堆栈区域”。这很好用 但是我故意犯了一个错误,而是再次按ALT+I,例如三次。看起来什么都没发生 但是现在,如果我尝试将窗口从“主区域”返回到“堆栈区域”,我首先需要再按ALT+d三次,然后什么也不会发生!最后,当我第四次按ALT+d时,窗口管理器会将第一个窗口从“主区域”的底部返回到“堆栈区域”的顶部 所以这不是经过深思熟虑的,应该被认为是一个bugX-DWM——帮助我修复C源代码中的一个bug,c,x-dwm,C,X Dwm,我正在使用(6.2)窗口管理器,我发现了一个我很想解决的bug 窗口管理器在放置窗口的位置使用“主区域”和“堆栈区域”: 可以使用ALT+i将“堆栈区域”顶部的窗口移动到“主区域”底部。也可以使用ALT+d将窗口从“主区域”的底部移回“堆栈区域”的顶部 现在,在这种情况下,如果我使用ALT+I,布局会改变,在组合键之后,“主区域”中有两个窗口: 我再重复一遍,现在“主区域”中有三个窗口: 我再重复一遍,现在“主区域”中有三个窗口,宽度为100%: 如果此时我决定将窗口从“主区域”返回到“
源代码中一定有某种计数器,按ALT+i再增加三倍,但在所有窗口都已位于“主区域”后,计数器不应增加
在
config.def.h
源文件()中,有一部分代码用于分配密钥。在这里我可以看到,当用户按下ALT+I时,调用函数incnmaster()
,并传递一个参数。I=+1
(我不理解这个参数)
Key
是dwm.c
源文件()中的一个结构:
函数incnmaster()
在dwm.c
源文件()中定义:
其中arg
是指向arg
(arg*
)的指针,它是一个联合体(我不太明白如何处理参数。I=+1
):
selmon
是一种结构Monitor
:
struct Monitor {
char ltsymbol[16];
float mfact;
int nmaster;
int num;
int by; /* bar geometry */
int mx, my, mw, mh; /* screen size */
int wx, wy, ww, wh; /* window area */
unsigned int seltags;
unsigned int sellt;
unsigned int tagset[2];
int showbar;
int topbar;
Client *clients;
Client *sel;
Client *stack;
Monitor *next;
Window barwin;
const Layout *lt[2];
};
struct Monitor {
char ltsymbol[16];
float mfact;
int nmaster;
int nclients;
int num;
int by; /* bar geometry */
int mx, my, mw, mh; /* screen size */
int wx, wy, ww, wh; /* window area */
unsigned int seltags;
unsigned int sellt;
unsigned int tagset[2];
int showbar;
int topbar;
Client *clients;
Client *sel;
Client *stack;
Monitor *next;
Window barwin;
const Layout *lt[2];
};
MAX
在单独的源文件util.h
()中定义为:
函数arrange()
的定义如下:
void
arrange(Monitor *m)
{
if (m)
showhide(m->stack);
else for (m = mons; m; m = m->next)
showhide(m->stack);
if (m) {
arrangemon(m);
restack(m);
} else for (m = mons; m; m = m->next)
arrangemon(m);
}
我想我不必再挖了
现在我认为我需要在C代码中实现某种类型的
if
语句,以防止selmon->nmaster
增加太多,但我有点困惑。有人能帮忙吗?在我自己弄明白这个问题之前,没有人回答。问题是,无吸团队从未实现任何类型的机制来计算打开的窗口数(他们称之为客户机)。这就是为什么我添加了int-nclients代码>结构的成员监视器:
struct Monitor {
char ltsymbol[16];
float mfact;
int nmaster;
int num;
int by; /* bar geometry */
int mx, my, mw, mh; /* screen size */
int wx, wy, ww, wh; /* window area */
unsigned int seltags;
unsigned int sellt;
unsigned int tagset[2];
int showbar;
int topbar;
Client *clients;
Client *sel;
Client *stack;
Monitor *next;
Window barwin;
const Layout *lt[2];
};
struct Monitor {
char ltsymbol[16];
float mfact;
int nmaster;
int nclients;
int num;
int by; /* bar geometry */
int mx, my, mw, mh; /* screen size */
int wx, wy, ww, wh; /* window area */
unsigned int seltags;
unsigned int sellt;
unsigned int tagset[2];
int showbar;
int topbar;
Client *clients;
Client *sel;
Client *stack;
Monitor *next;
Window barwin;
const Layout *lt[2];
};
然后我通过添加m->nclients=0,确保在启动时将其初始化为0
代码>在createmon()
函数中,我猜该函数是在开头运行的:
Monitor *
createmon(void)
{
Monitor *m;
m = ecalloc(1, sizeof(Monitor));
m->tagset[0] = m->tagset[1] = 1;
m->mfact = mfact;
m->nmaster = nmaster;
m->nclients = 0;
m->showbar = showbar;
m->topbar = topbar;
m->gappx = gappx;
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
return m;
}
然后,我确保当新窗口出现时,我的计数器nclients
会增加。我添加了++selmon->nclients代码>和排列(selmon)
(在关闭其中一个客户端后,能够立即将客户端移动到stack/master ime)函数开头的spawn()
语句:
void
spawn(const Arg *arg)
{
++selmon->nclients;
arrange(selmon);
if (arg->v == dmenucmd)
dmenumon[0] = '0' + selmon->num;
if (fork() == 0) {
if (dpy)
close(ConnectionNumber(dpy));
setsid();
execvp(((char **)arg->v)[0], (char **)arg->v);
fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
perror(" failed");
exit(EXIT_SUCCESS);
}
}
void
killclient(const Arg *arg)
{
--selmon->nclients;
arrange(selmon);
if (!selmon->sel)
return;
if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) {
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);
XSetCloseDownMode(dpy, DestroyAll);
XKillClient(dpy, selmon->sel->win);
XSync(dpy, False);
XSetErrorHandler(xerror);
XUngrabServer(dpy);
}
}
当车窗关闭时,计数器应减小。这就是为什么我添加了--selmon->nclients代码>和排列(selmon)
(在关闭其中一个客户端后,能够立即将客户端移动到stack/master i中)位于killclient()函数顶部:
void
spawn(const Arg *arg)
{
++selmon->nclients;
arrange(selmon);
if (arg->v == dmenucmd)
dmenumon[0] = '0' + selmon->num;
if (fork() == 0) {
if (dpy)
close(ConnectionNumber(dpy));
setsid();
execvp(((char **)arg->v)[0], (char **)arg->v);
fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
perror(" failed");
exit(EXIT_SUCCESS);
}
}
void
killclient(const Arg *arg)
{
--selmon->nclients;
arrange(selmon);
if (!selmon->sel)
return;
if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) {
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);
XSetCloseDownMode(dpy, DestroyAll);
XKillClient(dpy, selmon->sel->win);
XSync(dpy, False);
XSetErrorHandler(xerror);
XUngrabServer(dpy);
}
}
现在计数器已经设置好,我可以用它重写incnmaster()
函数,如下所示:
void
incnmaster(const Arg *arg)
{
if((arg->i > 0) && (selmon->nmaster < selmon->nclients)){
++selmon->nmaster;
}
if((arg->i < 0) && (selmon->nmaster > 0)){
--selmon->nmaster;
}
arrange(selmon);
}
void
incnmaster(常量参数*Arg)
{
if((arg->i>0)和&(selmon->nmasternclients)){
++selmon->nmaster;
}
if((arg->i<0)和&(selmon->nmaster>0)){
--selmon->nmaster;
}
安排(塞尔蒙);
}
注意。我的DWM有点补丁,所以有些行可能有点问题
与你的不同,但只要坚持同样的理念
我能解决这个问题
这个解决方案部分有效。只有当我:
A.使用dmenu
dmenu
启动时可以(a)打开客户端或(b)不执行任何操作。如果(a)一切正常,但如果(b)nmaster
和n客户端再次失去同步
因此,例如,如果我执行场景(b)一次,并无数次使用CTRL+I,我将不得不使用CTRL+d一次,什么也不会发生,但如果我再次使用它,一个窗口将从主窗口移动到堆栈区域
B.从终端运行任何类型的窗口应用程序
看起来DWM无法跟踪从终端运行的窗口并以错误的方式处理它们。。。在这种情况下,nmaster
和nclients
也会变得不同步
有人知道在打开任何类型的窗口时,除了执行spawn
之外,是否还有其他功能
这还没有解决 当它是一个链表时,为什么你要持有客户数量?您无法按需获取客户数量。类似的代码也可以找到。如果您真的必须自己计算(出于性能原因),我会查看dwm修改客户机列表的任何地方,并将该修改投影到计数器
结构客户机包含指向“下一个”客户机的指针,实现可能取决于何时需要使用multihead su
void
incnmaster(const Arg *arg)
{
if((arg->i > 0) && (selmon->nmaster < selmon->nclients)){
++selmon->nmaster;
}
if((arg->i < 0) && (selmon->nmaster > 0)){
--selmon->nmaster;
}
arrange(selmon);
}