clusterssh (Cssh) KDE下无法正确重排窗口的问题

cssh 是一个不错的多服务器登录工具, 采用平铺窗口的方式, 相比konsole的多tab, 更来得直观。 我也把它融合到自己的myssh中。

cssh在打开多窗口后, 会有个重排窗口使之不重叠的功能, 之前在gnome下用很正常, 但现在换到KDE, 却发现重排后依然没变化,乱且重叠了。搜了下,还真没找到啥解决方法, 想想cssh是perl写的, 就硬着头皮看看, 希望能解决这个小问题

稍微看了下函数, 发现有个与窗口重排有关的send_resizemove, 从函数名应该可以猜到它的作用。 整个cssh中, 只有一处地方调用了这函数. 大概在1367行。

        logmsg( 2, "Moving $server window" );
        send_resizemove(
            $servers{$server}{wid},
            $current_x, $current_y,
            $config{internal_terminal_width},    #该参数指定了重排时窗口的新宽度
            $config{internal_terminal_height}    #该参数指定了重排时窗口的新高度
        );

我修改了代码中最后两个参数, 并打开logmsg的调试信息, 希望能找到无法重排及重新调整窗口大小的问题。 写死了新的窗口大小, 但出来的结果却是只有最后一个窗口会改变大小, 其他窗口都没变化, 这倒很有意思, 不是send_resizemove无法起作用, 而是无法在全部窗口起作用。

Tiling top left going bot right
x:5 y:5, r:0 c:0
Moving 15.238.122.15  window
Moving window 65011726 to x:5 y:5 (size x:488 y:242)
x:498 y:5, r:0 c:1
Moving 15.238.122.16  window
Moving window 88080398 to x:498 y:5 (size x:488 y:242)
x:991 y:5, r:0 c:2
Moving 15.238.122.17  window
Moving window 75497486 to x:991 y:5 (size x:488 y:242)
x:1484 y:5, r:0 c:3
Moving 15.238.122.18  window
Moving window 62914574 to x:1484 y:5 (size x:488 y:242)
x:1977 y:5, r:0 c:4
Moving 115.238.122.19  window
Moving window 83886094 to x:1977 y:5 (size x:488 y:242)
x:2470 y:5, r:0 c:5
Moving 15.238.122.20  window
Moving window 92274702 to x:2470 y:5 (size x:488 y:242)
x:5 y:252, r:1 c:0
Moving 15.238.122.22  window
Moving window 77594638 to x:5 y:252 (size x:488 y:242)
x:498 y:252, r:1 c:1
Moving 15.238.122.23  window
Moving window 67108878 to x:498 y:252 (size x:488 y:242)
x:991 y:252, r:1 c:2
Moving 15.238.122.24  window
Moving window 69206030 to x:991 y:252 (size x:488 y:242)
x:1484 y:252, r:1 c:3
Moving 15.238.122.25  window
Moving window 73400334 to x:1484 y:252 (size x:488 y:242)
x:1977 y:252, r:1 c:4
Moving 15.238.122.26  window
Moving window 71303182 to x:1977 y:252 (size x:488 y:242)
x:2470 y:252, r:1 c:5
Moving 15.238.122.27  window
Moving window 81788942 to x:2470 y:252 (size x:488 y:242)
x:5 y:499, r:2 c:0
Moving 15.238.122.29  window
Moving window 79691790 to x:5 y:499 (size x:488 y:242)
x:498 y:499, r:2 c:1
Moving 15.238.122.20  window
Moving window 94371854 to x:498 y:499 (size x:488 y:242)
x:991 y:499, r:2 c:2
Moving 15.238.122.21  window
Moving window 90177550 to x:991 y:499 (size x:488 y:242)
x:1484 y:499, r:2 c:3
Moving 15.238.122.22  window
Moving window 96469006 to x:1484 y:499 (size x:488 y:242)
x:1977 y:499, r:2 c:4
Moving 15.238.122.23  window
Moving window 85983246 to x:1977 y:499 (size x:488 y:242)
x:2470 y:499, r:2 c:5
Moving 15.238.122.24  window
Moving window 111149070 to x:2470 y:499 (size x:488 y:242)
Setting focus on 15.238.122.24
Setting focus on 15.238.122.23
Setting focus on 15.238.122.22
Setting focus on 15.238.122.21
Setting focus on 15.238.122.20
Setting focus on 15.238.122.29
Setting focus on 15.238.122.27
Setting focus on 15.238.122.26
Setting focus on 15.238.122.15
Setting focus on 15.238.122.24
Setting focus on 15.238.122.23
Setting focus on 15.238.122.22
Setting focus on 15.238.122.20
Setting focus on 15.238.122.19
Setting focus on 15.238.122.18
Setting focus on 15.238.122.17
Setting focus on 15.238.122.16
Setting focus on 15.238.122.15
Sending console to front

这是cssh的调试信息中与窗口重排相关的部分, 最后的Setting focus 提示了我, 当前是重排所有窗口后, 再把焦点逐个定位到每个窗口(相当于鼠标点中的窗口状态), 是否在KDE下没有做这一步就无法调整大小? 根据Setting focus, 我找到了cssh中 相关的代码

    # Now remap in right order to get overlaps correct
    if ( $config{window_tiling_direction} =~ /right/i ) {
        foreach my $server ( reverse(@hosts) ) {
            logmsg( 2, "Setting focus on $server" );
            $xdisplay->req( 'MapWindow', $servers{$server}{wid} );

            # flush every time and wait a moment (The WMs are so slow...)
            $xdisplay->flush();
            select( undef, undef, undef, 0.1 );    # sleep for a mo
        }
    }
    else {
        foreach my $server (@hosts) {
            logmsg( 2, "Setting focus on $server" );
            $xdisplay->req( 'MapWindow', $servers{$server}{wid} );

            # flush every time and wait a moment (The WMs are so slow...)
            $xdisplay->flush();
            select( undef, undef, undef, 0.1 );    # sleep for a mo
        }
    }

不难看出, ‘$xdisplay->req( ‘MapWindow’, $servers{$server}{wid} );’ 这一句就是我要的, $servers{$server}{wid} 就是窗口的ID, 依葫芦画瓢, 我加了这么一句到send_resizemove的函数调用之前

       logmsg( 2, "Moving $server window" );
       $xdisplay->req( 'MapWindow', $servers{$server}{wid} );
        send_resizemove(
            $servers{$server}{wid},
            $current_x, $current_y,
            $config{internal_terminal_width},    #该参数指定了重排时窗口的新宽度
            $config{internal_terminal_height}    #该参数指定了重排时窗口的新高度
        );

很幸运的, 确实如我所想, 终于能在KDE下正确重排窗口了!!

bash重定向详解

首先我们先回顾下bash现有的重定向符号

1.重定向输入输出,目标是文件word

[n]<word    默认n为0
[n]>word    默认n为1
[n]>|word   默认n为1    noclobber选项有关,直接例子就明白它的用处了
[n]>>word   默认n为1
igi@igi-debian:~$ rm -f testfile
igi@igi-debian:~$ touch testfile
igi@igi-debian:~$ cat testfile
igi@igi-debian:~$ set -o noclobber
igi@igi-debian:~$ echo 2 >testfile
bash: testfile: cannot overwrite existing file
igi@igi-debian:~$ echo 2 >| testfile
igi@igi-debian:~$ cat testfile
2

2.重定向标准错误和标准输出到指定文件描述符

&>word      更通用
>&word
>word 2>&1

追加输出

&>>word     没有>>&word的表达方法
>>word 2>&1

3.Here Documents

 <<[-]word
   here-document
delimiter
-符号将删除所有行开头的tab符

4.Here Strings

<<<word

5.复制文件描述符

[n]<&word   默认n为0,如果为数字,必须得为打开的文件描述符
[n]<&-      关闭文件描述符

[n]>&word   默认n为1,如果为数字,必须得为打开的文件描述符
[n]>&-      关闭文件描述符

6.移动文件描述符

[n]<&digit- 默认n为0
[n]>&digit- 默认n为1

7.以读写方式打开文件描述符

[n]<>word   文件不在时会被创建

如果要深刻理解重定向,先要明白以下2点
1.shell(bash或者csh等)负责重定向,对于程序或者函数,这一切都是透明的,它只管输入输出,至于从哪输入哪输出,是shell解释器负责
2.shell命令解析过程中,在实际执行命令前,IO重定向先设置好

我们来看以下的例子

1.’echo 1 a1 >a2′ 与 ‘echo 1 >a2 a1′

igi@igi-debian:~$ echo 1 a1 >a2
igi@igi-debian:~$ cat a2
1 a1
igi@igi-debian:~$ rm a2
igi@igi-debian:~$ echo 1 >a2 a1
igi@igi-debian:~$ cat a2
1 a1

IO重定向是在命令执行前设置好,所以上面两种情况,最后的效果一样,bash先把输出重定向到a2文件,再执行’echo 1 a1′

2.’ls nothisfile >res 2>&1′ 与 ‘ls nothisfile 2>&1 >res’

igi@igi-debian:~/rtest$ ls nothisfile
ls: cannot access nothisfile: No such file or directory
igi@igi-debian:~/rtest$ ls nothisfile >res 2>&1
igi@igi-debian:~/rtest$ cat res
ls: cannot access nothisfile: No such file or directory
igi@igi-debian:~/rtest$ ls nothisfile 2>&1 >res
ls: cannot access nothisfile: No such file or directory
igi@igi-debian:~/rtest$ cat res
igi@igi-debian:~/rtest$ ls -1
a
b
c
res
igi@igi-debian:~/rtest$ ls -1 2>&1 >res
igi@igi-debian:~/rtest$ cat res
a
b
c
res

‘ls nothisfile >res 2>&1′,文件描述符1被重定向到文件res(本来是标准输出),然后再把文件描述符2重定向到文件描述符1(此时是文件描述符1指向文件res),最后执行”ls nothisfile”,产生错误,被送往文件描述符2,最后流向文件res。
‘ls nothisfile 2>&1 >res’,文件描述符2被重定向到文件描述符1(即标准输出:屏幕),然后再把文件描述符1重定向到文件res,结果是文件描述符2被重定向到标准输出,文件描述符1被重定向到文件res,最后执行”ls nothisfile”产生的错误就被送往屏幕。

3.’ls nothisfile a >&word’ 与 ‘ls nothisfile a >&123456′

igi@igi-debian:~/test/shell$ ls -1
a
igi@igi-debian:~/test/shell$ cat a
this is a
igi@igi-debian:~/test/shell$ ls nothisfile a >&word
igi@igi-debian:~/test/shell$ cat word
ls: cannot access nothisfile: No such file or directory
a
igi@igi-debian:~/test/shell$ ls nothisfile a >&123456
-bash: 123456: Bad file descriptor
igi@igi-debian:~/test/shell$ cat 123456
cat: 123456: No such file or directory

>&这个重定向符号,在前面有提到,“重定向标准错误和标准输出到指定文件描述符“ 和 “复制文件描述符“ 都有这个符号, 实际上“重定向标准错误和标准输出到指定文件描述符“ 是 “复制文件描述符“ 的一种特别情况, 即当 [n]>&word 的n省略 且 word不是数字时, 会重定向标准错误和标准输出 到指定文件。
“ls nothisfile a >&word” , 由于word不是纯数字, bash解析成 ”重定向标准错误和标准输出到指定文件描述符“, 效果相当于 ” ls nothisfile a >word 2>&1″
“ls nothisfile a >&123456″, 由于123456是纯数字, bash解析成 “复制文件描述符”, 相当于 ” ls nothisfile a 1>&123456″ , 但由于 “ 复制文件描述符 “规定 “如果为数字,必须得为打开的文件描述符”
所以发生了错误。

4.’ls a 1>&-’ 与 ‘ ls a >&1- ‘

igi@igi-debian:~/test/shell$ ls
a
igi@igi-debian:~/test/shell$ cat a
this is a
igi@igi-debian:~/test/shell$ ls a >&1-
a
igi@igi-debian:~/test/shell$ ls a 1>&-
ls: write error: Bad file descriptor

“ ls a >&1- “, >&1-属于“移动文件描述符” 提到的 “[n]>&digit-”, 用文件描述符digit替换掉文件描述符n, n描述符被关闭.n默认为1. “ls a >&1-”, 相当与 ” ls a 1>&1- “, 把文件描述符1替换掉原
文件描述符1, 然后关闭原文件描述符1, 没发生变化, 输出依然被送到屏幕
” ls a 1>&- “, >&- 属于 “复制文件描述符” 提到的”关闭文件描述符”, ” ls a 1>&- “, 关闭了文件描述符1, 在运行” ls a”, 由于输出默认都送到文件描述符1, 而它被关闭, 报”错误的文件描述符”

5.’ls a nothisfile 1>&2-’ 与 ‘ ls a nothisfile 1<&2- '

igi@igi-debian:~/test/shell$ ls -1
a
igi@igi-debian:~/test/shell$ ls a nothisfile 1<&2-
a
igi@igi-debian:~/test/shell$ ls a nothisfile 1>&2-
a
igi@igi-debian:~/test/shell$ exec 3<>test
igi@igi-debian:~/test/shell$ ls a nothisfile 1>&3-
ls: cannot access nothisfile: No such file or directory
igi@igi-debian:~/test/shell$ cat test
a
igi@igi-debian:~/test/shell$

‘ 1>&2- ‘ 与 ‘ 1<&2- ' 是一个效果的, [n]>&digit- 和 [n]<&digit- 这两个移动文件描述符的操作, 都是移动digit 到 n , 区别在n没有指定时, <&digit- 等于 0<&digit-, 而 >&digit- 等于 1>&digit-
移动文件描述符, 就是把描诉符digit的指向给描述符n, 然后关了digit. 例子中的exec很好的解释移动文件描述符的行为, 文件描述符3被定向到文件test, 然后1>&3-, 会使得1也定向到3所定向的文件test, 然后文件描诉符3被关闭, 效果就是标准输出被定向到test文件.

第 4 页,共 7 页« 最新...23456...最旧 »