我有多个“桌面”,我在KDE Linux环境中为不同的任务切换。如何自动确定我的Konsole(kde控制台)窗口显示在哪个桌面?
编辑: 我在企业环境中使用KDE 3.4
这与编程有关。我需要以编程方式(自动a.k.a.)确定用户所在的桌面,然后从python脚本与该桌面中的X窗口进行交互。
我是否应该绕过并解决所有Microsoft IDE问题,因为这与编程无关? Win32“编程”问题怎么样?我是否应该尝试关闭它们?
答案 0 :(得分:5)
实际上 EWMH _NET_CURRENT_DESKTOP
会为您提供X的当前桌面,而不是相对于应用程序的桌面。这是一个获取应用程序_WM_DESKTOP
的C片段。如果从有问题的KDE Konsole运行,它将为您提供它所在的桌面,即使它不是活动桌面或不是焦点。
#include <X11/Xlib.h>
#include <X11/Shell.h>
...
Atom net_wm_desktop = 0;
long desktop;
Status ret;
/* see if we've got a desktop atom */
Atom net_wm_desktop = XInternAtom( display, "_NET_WM_DESKTOP", False);
if( net_wm_desktop == None ) {
return;
}
/* find out what desktop we're currently on */
if ( XGetWindowProperty(display, window, net_wm_desktop, 0, 1,
False, XA_CARDINAL, (Atom *) &type_ret, &fmt_ret,
&nitems_ret, &bytes_after_ret,
(unsigned char**)&data) != Success || data == NULL
) {
fprintf(stderr, "XGetWindowProperty() failed");
if ( data == NULL ) {
fprintf(stderr, "No data returned from XGetWindowProperty()" );
}
return;
}
desktop = *data;
XFree(data);
和desktop
应该是Konsole当前所在虚拟桌面的索引。这与多头显示的头部不同。如果你想确定哪个头,你需要使用XineramaQueryScreens
(Xinerama扩展,不确定是否有XRandR等效。不适用于nVidia的TwinView。
以下是我编写的一些代码的摘录,给出了x和y,计算屏幕边界(sx,sy和sw,屏幕宽度为sh,屏幕高度为sh)。您可以轻松地调整它以简单地返回“屏幕”或头部x和y打开。 (屏幕在X11中有特殊含义。)
#include <X11/X.h>
#include <X11/extensions/Xinerama.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
Bool xy2bounds(Display* d,int x, int y, int* sx, int* sy, int* sw, int* sh) {
*sx = *sy = *sw = *sh = -1; /* Set to invalid, for error condition */
XineramaScreenInfo *XinInfo;
int xin_screens = -1;
int i;
int x_origin, y_origin, width, height;
Bool found = False;
if ( d == NULL )
return False;
if ( (x < 0) || (y < 0) )
return False;
if ( True == XineramaIsActive(d) ) {
XinInfo = XineramaQueryScreens( d, &xin_screens );
if ( (NULL == XinInfo) || (0 == xin_screens) ) {
return False;
}
} else {
/* Xinerama is not active, so return usual width/height values */
*sx = 0;
*sy = 0;
*sw = DisplayWidth( d, XDefaultScreen(d) );
*sh = DisplayHeight( d, XDefaultScreen(d) );
return True;
}
for ( i = 0; i < xin_screens; i++ ) {
x_origin = XinInfo[i].x_org;
y_origin = XinInfo[i].y_org;
width = XinInfo[i].width;
height = XinInfo[i].height;
printf("Screens: (%d) %dx%d - %dx%d\n", i,
x_origin, y_origin, width, height );
if ( (x >= x_origin) && (y >= y_origin) ) {
if ( (x <= x_origin+width) && (y <= y_origin+height) ) {
printf("Found Screen[%d] %dx%d - %dx%d\n",
i, x_origin, y_origin, width, height );
*sx = x_origin;
*sy = y_origin;
*sw = width;
*sh = height;
found = True;
break;
}
}
}
assert( found == True );
return found;
}
答案 1 :(得分:3)
KDE窗口管理器,以及遵循freedesktop标准的GNOME和所有WM都支持Extended Window Manager Hints(EWMH)。
这些提示允许开发人员以编程方式访问多个窗口管理器功能,如最大化,最小化,设置窗口标题,虚拟桌面e.t.c
我从未使用过KDE,但是Gnome提供了这样的功能,所以我认为KDE也有它。
也可以使用纯Xlib函数访问这些提示的子集。该子集是ICCCM提示。如果内存为我提供了正确的虚拟桌面访问仅在EWMH中。
更新:Found它! (_NET_CURRENT_DESKTOP
)
答案 2 :(得分:3)
参考接受的答案...... dcop现已过时;您可能希望使用dbus而不是dcop(qdbus是dbus的命令行工具)。
qdbus org.kde.kwin /KWin currentDesktop
答案 3 :(得分:2)
使用dc,kde桌面通信协议,您可以轻松获得当前桌面执行
dcop kwin KWinInterface currentDesktop
命令。如果您正在使用新的kde 4.x dcop不再使用,您可以将命令转换为DBUS调用。使用python apis发送/获取dbous消息应该非常简单。
抱歉我的英文不好, 埃米利奥
答案 4 :(得分:2)
一个新的答案,因为这里的答案大部分都是当前桌面,而不是终端所在的桌面(如果用户在脚本运行时更改桌面,则会中断)。
xprop -id $WINDOWID | sed -rn -e 's/_NET_WM_DESKTOP\(CARDINAL\) = ([^)]+)/\1/pg'
我在更换桌面时循环测试了它,它运行正常(测试脚本如下,你必须在运行后手动检查输出)。
while true
do
xprop -id $WINDOWID | sed -rn -e 's/_NET_WM_DESKTOP\(CARDINAL\) = ([^)]+)/\1/pg'
sleep 1
done
感谢其他答案和评论,让我在那里一半。
答案 5 :(得分:0)
我一直在寻找相同的东西,但是又有一个限制,我不想运行shell命令来获得结果。从Kimball Robinson的答案开始,这就是我所得到的。
经过测试可在Python3.7,Debian 10.3,KDE Plasma 5.14.5中工作。
import dbus
bus = dbus.SessionBus()
proxy = bus.get_object("org.kde.KWin", "/KWin")
int( proxy.currentDesktop(dbus_interface="org.kde.KWin") )