2009-04-10 7 views
4

Ich habe mehrere "Desktops", zwischen denen ich für verschiedene Aufgaben in meiner KDE-Linux-Umgebung wechseln kann. Wie kann ich automatisch bestimmen, auf welchem ​​Desktop mein Konsole (kde console) Fenster angezeigt wird?Wie erkenne ich in KDE automatisch, an welchem ​​"Desktop" sich ein Konsole-Terminal befindet?

EDIT: Ich verwende KDE 3.4 in einer Unternehmensumgebung

Dies betraf programmiert. Ich muss programmatisch (auch automatisch) feststellen, auf welchem ​​Desktop ein Benutzer ist, und dann mit X-Fenstern in diesem Desktop von einem Python-Skript aus interagieren.

Sollte ich herumgehen und alle Microsoft IDE-Fragen als nicht programmierungsrelevant behandeln? Wie wäre es mit Win32 "Programmierung" Fragen? Soll ich diese auch schließen?

+0

Warum versuchen Sie, dies zu bestimmen? Was wirst du mit dem Ergebnis machen, wenn du es gefunden hast? Ohne es zu wissen, lautet die beste Antwort: "Klicken Sie auf die Konsole-Schaltfläche in Ihrer Taskleiste und sehen Sie, auf welchen Desktop sie wechselt." – davr

+0

mindestens einige Infos sind erforderlich. kde4, kde3? Welche Version der Konsole? –

+1

Ich muss den Desktop im Code ermitteln, nicht indem ich einen Benutzer auffordere, mir zu sagen, auf welchem ​​Desktop er sich befindet. –

Antwort

2

Mit dcop, erhält der kDE-Desktop Communication Protocol, könnte man leicht aktuelle Desktop-Ausführung

dcop kwin KWinInterface currentDesktop 

Befehl. Wenn Sie mit neuem kde 4.x arbeiten, wird dcop nicht mehr verwendet und Sie können den Befehl in einen DBUS-Aufruf übersetzen. Es sollte ziemlich einfach sein, dbous Nachrichten mit Python Apis zu senden/zu erhalten.

Sorry für mein schlechtes Englisch, Emilio

+2

Endlich eine KDE/Gnome-agnostische Version des obigen Befehls gefunden. Es ist 'xprop-root | egrep '^ _NET_CURRENT_DESKTOP'' –

+0

dcop ist nicht mehr aktuell; anstelle von dcop möchten Sie vielleicht dbus verwenden. Siehe meine alternative Antwort unten. –

3

Der KDE-Fenstermanager sowie GNOME und alle WMs, die den freedesktop-Standards folgen, unterstützen die Extended Window Manager Hints (EWMH).

Diese Hinweise können Entwickler Funktionen programmatisch mehrere Fenster-Manager wie Maximierungs zuzugreifen, zu minimieren, setzen Fenstertitel, virtuelle Desktop etc

ich nie mit KDE gearbeitet haben, aber Gnome bietet eine solche Funktionalität so nehme ich an, dass KDE es auch hat .

Es ist auch möglich, auf eine Teilmenge dieser Hinweise mit reinen Xlib Funktionen zuzugreifen. Diese Teilmenge sind ICCCM Hinweise. Wenn der Speicher für mich funktioniert, ist der korrekte Zugriff auf den virtuellen Desktop nur in EWMH.

Update: Found it! (_NET_CURRENT_DESKTOP)

5

Eigentlich EWMH_NET_CURRENT_DESKTOP geben Sie die den aktuellen Desktop für X ist, nicht in Bezug auf die Anwendung. Hier ist ein C-Ausschnitt, um die _WM_DESKTOP einer Anwendung zu erhalten. Wenn es von der betreffenden KDE-Konsole ausgeführt wird, zeigt es Ihnen, auf welchem ​​Desktop es sich befindet, selbst wenn es sich nicht um den aktiven Desktop oder nicht um den Fokus handelt.

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

und desktop sollte der Index des virtuellen Desktop kann die Konsole ist zur Zeit in. Das ist nicht das gleiche, die Spitze einer mehrköpfigen Display. Wenn Sie bestimmen möchten, welcher Kopf, müssen Sie XineramaQueryScreens (Xinerama Erweiterung, nicht sicher, ob es ein XRandR entspricht oder nicht. Funktioniert nicht für nVidia TwinView.

Hier ist ein Auszug aus einem Code ich schrieb, dass gegeben ax und y, berechnen Sie die Bildschirmgrenzen (sx, sy und sw mit Bildschirmbreite und sh für Bildschirmhöhe) Sie können es einfach anpassen, um einfach zurückzukehren, welcher "Bildschirm" oder Kopf x und y sind. (Bildschirm hat eine spezielle in X11 Bedeutung.)

#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; 
} 
+0

Wow! Vielen Dank. –

+0

Ich arbeite mich durch den Beispielcode, aber ich kann nicht herausfinden, wie man eine "Fenster" -Schaltfläche zum Konsole-Fenster bringt. –

+1

Ich hatte dieses Detail vergessen, aber es sollte mit 'xwininfo' oder' xprop' möglich sein. – mctylr

2

auf die akzeptierte Antwort Bezug .... dcop jetzt ist veraltet; anstelle von dcop möchten Sie vielleicht dbus verwenden (qdbus ist ein Kommandozeilenwerkzeug für dbus).

qdbus org.kde.kwin /KWin currentDesktop 
2

Eine neue Antwort, weil die meisten Antworten hier den aktuellen Desktop erhalten, nicht derjenige, der Terminal in ist (brechen wird, wenn der Benutzer-Desktop-Änderungen während das Script ausgeführt wird).

xprop -id $WINDOWID | sed -rn -e 's/_NET_WM_DESKTOP\(CARDINAL\) = ([^)]+)/\1/pg'

ich dies in einer Schleife getestet, während Desktops zu ändern, ist es ok funktioniert (Testskript unten, haben Sie die Ausgabe manuell nach dem Lauf zu überprüfen).

while true 
do 
    xprop -id $WINDOWID | sed -rn -e 's/_NET_WM_DESKTOP\(CARDINAL\) = ([^)]+)/\1/pg' 
    sleep 1 
done 

Danke für die anderen Antworten und Kommentare, um mich auf halbem Weg zu bekommen.

Verwandte Themen