2009-04-10 55 views
4

我有多個「桌面」,可以在我的KDE Linux環境中進行不同的任務切換。我如何自動確定我的Konsole(kde控制檯)窗口顯示在哪個桌面上?在KDE中,我如何自動判斷Konsole終端在哪個「桌面」?

編輯: 我在企業環境中

這是規劃的相關使用KDE 3.4。我需要以編程方式(a.k.a. automagically)確定用戶所在的桌面,然後從python腳本與該桌面中的X窗口進行交互。

我是否應該繞過所有微軟IDE問題去解決與編程無關的問題? Win32「編程」問題如何?我應該嘗試關閉這些嗎?

+0

你爲什麼試圖確定這一點?一旦找到結果,你將如何處理結果?在不知道的情況下,最好的答案是「單擊任務欄上的konsole按鈕,並查看切換到的桌面。」 – davr 2009-04-10 16:46:29

+0

至少需要一些信息。 kde4,kde3?什麼konsole版本? – 2009-04-10 17:01:39

+1

我需要在代碼中確定桌面,而不是要求用戶告訴我他們在哪個桌面上。 – 2009-04-10 17:21:57

回答

2

有了DCOP,KDE桌面通信協議,你可以很容易地獲取當前桌面執行

dcop kwin KWinInterface currentDesktop 

命令。如果您正在使用新的kde 4.x,則不再使用dcop,並且您可以將該命令轉換爲DBUS調用。使用python apis發送/獲取dbous消息應該非常簡單。

對不起我的英文不好, 埃米利奧

3

KDE窗口管理器,以及遵循freedesktop標準的GNOME和所有WM都支持Extended Window Manager Hints(EWMH)。

這些提示允許開發人員訪問編程幾個窗口管理功能,如最大化,最小化設置窗口標題,虛擬桌面等

我從來沒有與KDE工作,但侏儒提供了這樣的功能,所以我認爲KDE有它太。

也可以使用純Xlib函數訪問這些提示的子集。這個子集是ICCCM提示。如果內存爲我服務,則正確的虛擬桌面訪問權限僅限於EWMH。

更新:Found它! (_NET_CURRENT_DESKTOP

5

其實EWMH_NET_CURRENT_DESKTOP給你這是X目前的桌面,而不是相對於應用程序。這裏有一個C代碼片段來獲取應用程序的_WM_DESKTOP。如果從有問題的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; 
} 
2

參考接受的答案.... DCOP現在已經過時了;而不是dcop你可能想要使用dbus(qdbus是dbus的命令行工具)。

qdbus org.kde.kwin /KWin currentDesktop 
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 

感謝您的其他答案和評論,讓我走到一半。

相關問題