In KDE, how can I automatically tell which “Desktop” a Konsole terminal is in?

倖福魔咒の 提交于 2019-12-21 17:52:39

问题


I have multiple "desktops" that I switch between for different tasks in my KDE Linux environment. How can I automagically determine which desktop my Konsole ( kde console) window is being displayed in?

EDIT: I'm using KDE 3.4 in a corporate environment

This is programming related. I need to programatically (a.k.a. automagically ) determine which desktop a user is on and then interact with X windows in that desktop from a python script.

Should I go around and nuke all Microsoft IDE questions as not programming related? How about Win32 "programming" questions? Should I try to close those too?


回答1:


With dcop, the kde Desktop COmmunication Protocol, you could easily get current desktop executing

  dcop kwin KWinInterface currentDesktop

command. If you are working with new kde 4.x dcop is no more used, and you can translate the command to a DBUS call. It should be quite simple to send/get dbous messages with python apis.

Sorry for my bad english, Emilio




回答2:


Actually EWMH _NET_CURRENT_DESKTOP gives you which is the current desktop for X, not relative to the application. Here's a C snippet to get the _WM_DESKTOP of an application. If run from the KDE Konsole in question it will give you what desktop it is on, even it is not the active desktop or not in focus.

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

and desktop should be the index of the virtual desktop the Konsole is currently in. That is not the same which head of a multi-headed display. If you want to determine which head, you need to use XineramaQueryScreens (Xinerama extension, not sure if there is a XRandR equivalent or not. Does not work for nVidia's TwinView.

Here's an excerpt from some code I wrote, that given a x and y, calculate the screen boundaries (sx, sy, and sw with screen width and sh for screen height). You can easily adapt it to simply return which "screen" or head x and y are on. (Screen has a special meaning in 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;
}



回答3:


The KDE window manager, as well as GNOME and all WMs that follow the freedesktop standards support the Extended Window Manager Hints (EWMH).

These hints allow developers to access programmatically several window manager functions like maximize, minimize, set window title, virtual desktop e.t.c

I have never worked with KDE but Gnome provides such functionality so I assume that KDE has it too.

It is also possible to access a subset of these hints with pure Xlib functions. This subset are ICCCM hints. If memory serves me correct virtual desktop access is only in EWMH.

Update: Found it! (_NET_CURRENT_DESKTOP)




回答4:


Referring to the accepted answer.... dcop is now out of date; instead of dcop you might want to use dbus (qdbus is a command line tool for dbus).

qdbus org.kde.kwin /KWin currentDesktop



回答5:


A new answer because MOST of the answers here get the current desktop, not the one the terminal is in (Will break if user changes desktop while script is running).

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

I tested this in a loop while changing desktops, it works ok (test script bellow, you have to check the output manually after the run).

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

Thanks for the other answers and comments, for getting me half way there.



来源:https://stackoverflow.com/questions/738059/in-kde-how-can-i-automatically-tell-which-desktop-a-konsole-terminal-is-in

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!