5

我有多个“桌面”,可以在我的 KDE Linux 环境中为不同的任务切换。如何自动确定我的 Konsole(kde 控制台)窗口显示在哪个桌面?

编辑:我在企业环境中使用 KDE 3.4

这与编程有关。我需要以编程方式(也称为自动)确定用户在哪个桌面上,然后通过 python 脚本与该桌面中的 X 窗口进行交互。

我应该四处解决所有与编程无关的 Microsoft IDE 问题吗?Win32“编程”问题怎么样?我也应该尝试关闭它们吗?

4

6 回答 6

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。

这是我编写的一些代码的摘录,给定 ax 和 y,计算屏幕边界(sx、sy 和 sw 与屏幕宽度和 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;
}
于 2009-04-11T16:59:31.467 回答
5

参考接受的答案.... dcop 现在已过时;您可能想要使用 dbus 而不是 dcop(qdbus 是 dbus 的命令行工具)。

qdbus org.kde.kwin /KWin currentDesktop
于 2012-04-10T18:32:52.477 回答
3

KDE 窗口管理器以及 GNOME 和所有遵循freedesktop标准的 WM 都支持扩展窗口管理器提示(EWMH)。

这些提示允许开发人员以编程方式访问多个窗口管理器功能,如最大化、最小化、设置窗口标题、虚拟桌面等

我从未使用过 KDE,但 Gnome 提供了这样的功能,所以我认为 KDE 也有。

也可以使用纯Xlib函数访问这些提示的子集。该子集是ICCCM提示。如果记忆对我有用,那么正确的虚拟桌面访问仅在 EWMH 中。

更新:找到了!( _NET_CURRENT_DESKTOP)

于 2009-04-10T17:54:52.483 回答
2

使用 dcop,kde 桌面通信协议,您可以轻松地执行当前桌面

  dcop kwin KWinInterface currentDesktop

命令。如果您正在使用新的 kde 4.x dcop,则不再使用,您可以将命令转换为 DBUS 调用。使用 python api 发送/获取 dbous 消息应该非常简单。

对不起我的英语不好,埃米利奥

于 2009-04-13T20:24:53.250 回答
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

感谢其他答案和评论,让我走到了一半。

于 2014-03-07T13:09:59.563 回答
2

我一直在寻找同样的东西,但还有一个限制,我不想运行 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") )
于 2020-04-08T07:31:09.630 回答