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スニペットです。問題のKDEKonsoleから実行すると、アクティブデスクトップでなくても、フォーカスが合っていなくても、どのデスクトップ上にあるかがわかります。

#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);

Konsoleが現在使用している仮想デスクトップのインデックスである必要がありdesktopます。これは、マルチヘッドディスプレイのどのヘッドと同じではありません。どのヘッドを使用するかを決定する場合は、使用する必要があります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は古くなっています。dcop の代わりに dbus を使用することもできます (qdbus は dbus のコマンド ライン ツールです)。

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

KDE ウィンドウ マネージャー、および GNOME とfreedesktop標準に従うすべての WM は、 Extended Window Manager Hints (EWMH) をサポートしています。

これらのヒントにより、開発者は、最大化、最小化、ウィンドウ タイトルの設定、仮想デスクトップなどのいくつかのウィンドウ マネージャー機能にプログラムでアクセスできます。

私は KDE を使ったことはありませんが、Gnome にはそのような機能があるので、KDE ​​にもあると思います。

純粋なXlib関数を使用して、これらのヒントのサブセットにアクセスすることもできます。このサブセットはICCCMヒントです。メモリが役立つ場合、正しい仮想デスクトップへのアクセスは EWMH でのみ行われます。

更新:見つけた!( _NET_CURRENT_DESKTOP)

于 2009-04-10T17:54:52.483 に答える
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 に答える