На самом деле 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 или нет. Не работает для TwinView nVidia.
Вот выдержка из некоторого кода, который я написал, для которого даны x и 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;
}