Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 534
Ross Rogers Avatar asked Apr 10 '09 15:04

Ross Rogers


People also ask

How do I change Konsole terminal?

Configuring Konsole Profiles: To edit the current Konsole profile, go to Settings > Edit Current Profile… From the General tab, you can set a Profile name, set the default shell (Command), Initial directory when Konsole starts. You can also set custom environment variables if you want. Just click on Edit…

Where are Konsole settings stored?

All new and changed profiles are saved in the user's local home folder in $ XDG_DATA_HOME /konsole .

Is Konsole a good terminal emulator?

Konsole is one of the most advanced Linux terminal emulators. It is the default terminal emulator that ships with the KDE desktop environment. The emulator has a lot of advanced features such as support for hyperlinks and an "edit and view" feature to make the command line experience less complex.


1 Answers

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;
}
like image 159
mctylr Avatar answered Oct 04 '22 22:10

mctylr